Merge branch 'develop' into fix/3801

This commit is contained in:
Yash Singh
2024-07-16 13:05:44 -07:00
committed by GitHub
248 changed files with 18657 additions and 13887 deletions

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import { packageOptions } from './common.js'; import { packageOptions } from './common.js';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
@@ -5,11 +6,17 @@ const buildType = (packageName: string) => {
console.log(`Building types for ${packageName}`); console.log(`Building types for ${packageName}`);
try { try {
const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`); const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`);
out.length > 0 && console.log(out.toString()); if (out.length > 0) {
console.log(out.toString());
}
} catch (e) { } catch (e) {
console.error(e); console.error(e);
e.stdout.length > 0 && console.error(e.stdout.toString()); if (e.stdout.length > 0) {
e.stderr.length > 0 && console.error(e.stderr.toString()); console.error(e.stdout.toString());
}
if (e.stderr.length > 0) {
console.error(e.stderr.toString());
}
} }
}; };

View File

@@ -13,6 +13,7 @@ bqstring
BQUOTE BQUOTE
bramp bramp
BRKT BRKT
brotli
callbackargs callbackargs
callbackname callbackname
classdef classdef
@@ -111,6 +112,7 @@ STYLECLASS
STYLEOPTS STYLEOPTS
subcomponent subcomponent
subcomponents subcomponents
subconfig
SUBROUTINEEND SUBROUTINEEND
SUBROUTINESTART SUBROUTINESTART
Subschemas Subschemas
@@ -125,6 +127,7 @@ titlevalue
topbar topbar
TRAPEND TRAPEND
TRAPSTART TRAPSTART
treemap
ts-nocheck ts-nocheck
tsdoc tsdoc
typeof typeof

View File

@@ -4,5 +4,6 @@ cpettitt
Dong Cai Dong Cai
Nikolay Rozhkov Nikolay Rozhkov
Peng Xiao Peng Xiao
Per Brolin
subhash-halder subhash-halder
Vinod Sidharth Vinod Sidharth

View File

@@ -20,6 +20,7 @@ dagre-d3
Deepdwn Deepdwn
Docsify Docsify
Docsy Docsy
Doctave
DokuWiki DokuWiki
dompurify dompurify
elkjs elkjs
@@ -55,12 +56,14 @@ pyplot
redmine redmine
rehype rehype
rscratch rscratch
shiki
sparkline sparkline
sphinxcontrib sphinxcontrib
ssim ssim
stylis stylis
Swimm Swimm
tsbuildinfo tsbuildinfo
tseslint
Tuleap Tuleap
Typora Typora
unocss unocss

View File

@@ -1 +1,4 @@
BRANDES
handdrawn
KOEPF
newbranch newbranch

View File

@@ -2,7 +2,8 @@ import { build } from 'esbuild';
import { mkdir, writeFile } from 'node:fs/promises'; import { mkdir, writeFile } from 'node:fs/promises';
import { packageOptions } from '../.build/common.js'; import { packageOptions } from '../.build/common.js';
import { generateLangium } from '../.build/generateLangium.js'; import { generateLangium } from '../.build/generateLangium.js';
import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js'; import type { MermaidBuildOptions } from './util.js';
import { defaultOptions, getBuildConfig } from './util.js';
const shouldVisualize = process.argv.includes('--visualize'); const shouldVisualize = process.argv.includes('--visualize');
@@ -35,11 +36,11 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
if (shouldVisualize) { if (shouldVisualize) {
for (const { metafile } of results) { for (const { metafile } of results) {
if (!metafile) { if (!metafile?.outputs) {
continue; continue;
} }
const fileName = Object.keys(metafile.outputs) const fileName = Object.keys(metafile.outputs)
.filter((file) => !file.includes('chunks') && file.endsWith('js'))[0] .find((file) => !file.includes('chunks') && file.endsWith('js'))
.replace('dist/', ''); .replace('dist/', '');
// Upload metafile into https://esbuild.github.io/analyze/ // Upload metafile into https://esbuild.github.io/analyze/
await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile)); await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile));
@@ -48,13 +49,14 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
}; };
const handler = (e) => { const handler = (e) => {
// eslint-disable-next-line no-console
console.error(e); console.error(e);
process.exit(1); process.exit(1);
}; };
const main = async () => { const main = async () => {
await generateLangium(); await generateLangium();
await mkdir('stats').catch(() => {}); await mkdir('stats', { recursive: true });
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
// it should build `parser` before `mermaid` because it's a dependency // it should build `parser` before `mermaid` because it's a dependency
for (const pkg of packageNames) { for (const pkg of packageNames) {

View File

@@ -1,6 +1,6 @@
import { readFile } from 'node:fs/promises'; import { readFile } from 'node:fs/promises';
import { transformJison } from '../.build/jisonTransformer.js'; import { transformJison } from '../.build/jisonTransformer.js';
import { Plugin } from 'esbuild'; import type { Plugin } from 'esbuild';
export const jisonPlugin: Plugin = { export const jisonPlugin: Plugin = {
name: 'jison', name: 'jison',

View File

@@ -1,11 +1,12 @@
import express from 'express'; /* eslint-disable no-console */
import type { NextFunction, Request, Response } from 'express';
import cors from 'cors';
import { getBuildConfig, defaultOptions } from './util.js';
import { context } from 'esbuild';
import chokidar from 'chokidar'; import chokidar from 'chokidar';
import { generateLangium } from '../.build/generateLangium.js'; import cors from 'cors';
import { context } from 'esbuild';
import type { Request, Response } from 'express';
import express from 'express';
import { packageOptions } from '../.build/common.js'; import { packageOptions } from '../.build/common.js';
import { generateLangium } from '../.build/generateLangium.js';
import { defaultOptions, getBuildConfig } from './util.js';
const configs = Object.values(packageOptions).map(({ packageName }) => const configs = Object.values(packageOptions).map(({ packageName }) =>
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName }) getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName })
@@ -19,16 +20,28 @@ const mermaidIIFEConfig = getBuildConfig({
}); });
configs.push(mermaidIIFEConfig); configs.push(mermaidIIFEConfig);
const contexts = await Promise.all(configs.map((config) => context(config))); const contexts = await Promise.all(
configs.map(async (config) => ({ config, context: await context(config) }))
);
let rebuildCounter = 1;
const rebuildAll = async () => { const rebuildAll = async () => {
console.time('Rebuild time'); const buildNumber = rebuildCounter++;
await Promise.all(contexts.map((ctx) => ctx.rebuild())).catch((e) => console.error(e)); const timeLabel = `Rebuild ${buildNumber} Time (total)`;
console.timeEnd('Rebuild time'); console.time(timeLabel);
await Promise.all(
contexts.map(async ({ config, context }) => {
const buildVariant = `Rebuild ${buildNumber} Time (${Object.keys(config.entryPoints!)[0]} ${config.format})`;
console.time(buildVariant);
await context.rebuild();
console.timeEnd(buildVariant);
})
).catch((e) => console.error(e));
console.timeEnd(timeLabel);
}; };
let clients: { id: number; response: Response }[] = []; let clients: { id: number; response: Response }[] = [];
function eventsHandler(request: Request, response: Response, next: NextFunction) { function eventsHandler(request: Request, response: Response) {
const headers = { const headers = {
'Content-Type': 'text/event-stream', 'Content-Type': 'text/event-stream',
Connection: 'keep-alive', Connection: 'keep-alive',
@@ -45,19 +58,20 @@ function eventsHandler(request: Request, response: Response, next: NextFunction)
}); });
} }
let timeoutId: NodeJS.Timeout | undefined = undefined; let timeoutID: NodeJS.Timeout | undefined = undefined;
/** /**
* Debounce file change events to avoid rebuilding multiple times. * Debounce file change events to avoid rebuilding multiple times.
*/ */
function handleFileChange() { function handleFileChange() {
if (timeoutId !== undefined) { if (timeoutID !== undefined) {
clearTimeout(timeoutId); clearTimeout(timeoutID);
} }
timeoutId = setTimeout(async () => { // eslint-disable-next-line @typescript-eslint/no-misused-promises
timeoutID = setTimeout(async () => {
await rebuildAll(); await rebuildAll();
sendEventsToAll(); sendEventsToAll();
timeoutId = undefined; timeoutID = undefined;
}, 100); }, 100);
} }
@@ -74,15 +88,16 @@ async function createServer() {
ignoreInitial: true, ignoreInitial: true,
ignored: [/node_modules/, /dist/, /docs/, /coverage/], ignored: [/node_modules/, /dist/, /docs/, /coverage/],
}) })
// eslint-disable-next-line @typescript-eslint/no-misused-promises
.on('all', async (event, path) => { .on('all', async (event, path) => {
// Ignore other events. // Ignore other events.
if (!['add', 'change'].includes(event)) { if (!['add', 'change'].includes(event)) {
return; return;
} }
if (/\.langium$/.test(path)) { console.log(`${path} changed. Rebuilding...`);
if (path.endsWith('.langium')) {
await generateLangium(); await generateLangium();
} }
console.log(`${path} changed. Rebuilding...`);
handleFileChange(); handleFileChange();
}); });
@@ -99,4 +114,4 @@ async function createServer() {
}); });
} }
createServer(); void createServer();

View File

@@ -56,7 +56,7 @@ export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
const external: string[] = ['require', 'fs', 'path']; const external: string[] = ['require', 'fs', 'path'];
const { name, file, packageName } = packageOptions[entryName]; const { name, file, packageName } = packageOptions[entryName];
const outFileName = getFileName(name, options); const outFileName = getFileName(name, options);
let output: BuildOptions = buildOptions({ const output: BuildOptions = buildOptions({
absWorkingDir: resolve(__dirname, `../packages/${packageName}`), absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
entryPoints: { entryPoints: {
[outFileName]: `src/${file}`, [outFileName]: `src/${file}`,

View File

@@ -1 +0,0 @@
.gitignore

View File

@@ -1,190 +0,0 @@
module.exports = {
env: {
browser: true,
es6: true,
'jest/globals': true,
node: true,
},
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
tsconfigRootDir: __dirname,
sourceType: 'module',
ecmaVersion: 2022,
allowAutomaticSingleRunInference: true,
project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
parser: '@typescript-eslint/parser',
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:json/recommended',
'plugin:markdown/recommended-legacy',
'plugin:@cspell/recommended',
'prettier',
],
plugins: [
'@typescript-eslint',
'no-only-tests',
'html',
'jest',
'jsdoc',
'json',
'@cspell',
'lodash',
'unicorn',
],
ignorePatterns: [
// this file is automatically generated by `pnpm run --filter mermaid types:build-config`
'packages/mermaid/src/config.type.ts',
],
rules: {
curly: 'error',
'no-console': 'error',
'no-prototype-builtins': 'off',
'no-unused-vars': 'off',
'cypress/no-async-tests': 'off',
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-expect-error': 'allow-with-description',
'ts-ignore': 'allow-with-description',
'ts-nocheck': 'allow-with-description',
'ts-check': 'allow-with-description',
minimumDescriptionLength: 10,
},
],
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'typeLike',
format: ['PascalCase'],
custom: {
regex: '^I[A-Z]',
match: false,
},
},
],
'json/*': ['error', 'allowComments'],
'@cspell/spellchecker': [
'error',
{
checkIdentifiers: true,
checkStrings: true,
checkStringTemplates: true,
},
],
'no-empty': [
'error',
{
allowEmptyCatch: true,
},
],
'no-only-tests/no-only-tests': 'error',
'lodash/import-scope': ['error', 'method'],
'unicorn/better-regex': 'error',
'unicorn/no-abusive-eslint-disable': 'error',
'unicorn/no-array-push-push': 'error',
'unicorn/no-for-loop': 'error',
'unicorn/no-instanceof-array': 'error',
'unicorn/no-typeof-undefined': 'error',
'unicorn/no-unnecessary-await': 'error',
'unicorn/no-unsafe-regex': 'warn',
'unicorn/no-useless-promise-resolve-reject': 'error',
'unicorn/prefer-array-find': 'error',
'unicorn/prefer-array-flat-map': 'error',
'unicorn/prefer-array-index-of': 'error',
'unicorn/prefer-array-some': 'error',
'unicorn/prefer-default-parameters': 'error',
'unicorn/prefer-includes': 'error',
'unicorn/prefer-negative-index': 'error',
'unicorn/prefer-object-from-entries': 'error',
'unicorn/prefer-string-starts-ends-with': 'error',
'unicorn/prefer-string-trim-start-end': 'error',
'unicorn/string-content': 'error',
'unicorn/prefer-spread': 'error',
'unicorn/no-lonely-if': 'error',
},
overrides: [
{
files: ['cypress/**', 'demos/**'],
rules: {
'no-console': 'off',
},
},
{
files: ['*.{js,jsx,mjs,cjs}'],
extends: ['plugin:jsdoc/recommended'],
rules: {
'jsdoc/check-indentation': 'off',
'jsdoc/check-alignment': 'off',
'jsdoc/check-line-alignment': 'off',
'jsdoc/multiline-blocks': 'off',
'jsdoc/newline-after-description': 'off',
'jsdoc/tag-lines': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-description': 'off',
},
},
{
files: ['*.{ts,tsx}'],
plugins: ['tsdoc'],
rules: {
'no-restricted-syntax': [
'error',
{
selector: 'TSEnumDeclaration',
message:
'Prefer using TypeScript union types over TypeScript enum, since TypeScript enums have a bunch of issues, see https://dev.to/dvddpl/whats-the-problem-with-typescript-enums-2okj',
},
],
'tsdoc/syntax': 'error',
},
},
{
files: ['*.spec.{ts,js}', 'cypress/**', 'demos/**', '**/docs/**'],
rules: {
'jsdoc/require-jsdoc': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
{
files: ['*.spec.{ts,js}', 'tests/**', 'cypress/**/*.js'],
rules: {
'@cspell/spellchecker': [
'error',
{
checkIdentifiers: false,
checkStrings: false,
checkStringTemplates: false,
},
],
},
},
{
files: ['*.html', '*.md', '**/*.md/*'],
rules: {
'no-var': 'error',
'no-undef': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': 'off',
},
parserOptions: {
project: null,
},
},
],
};

5
.github/lychee.toml vendored
View File

@@ -41,7 +41,10 @@ exclude = [
"https://bundlephobia.com", "https://bundlephobia.com",
# Chrome webstore migration issue. Temporary # Chrome webstore migration issue. Temporary
"https://chromewebstore.google.com" "https://chromewebstore.google.com",
# Drupal 403
"https://(www.)?drupal.org"
] ]
# Exclude all private IPs from checking. # Exclude all private IPs from checking.

View File

@@ -18,7 +18,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@@ -18,7 +18,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js

View File

@@ -1,9 +1,3 @@
# We use github cache to save snapshots between runs.
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
# These are then downloaded before running the E2E, providing the reference snapshots.
# If there are any errors, the diff image is uploaded to artifacts, and the user is notified.
name: E2E name: E2E
on: on:
@@ -30,6 +24,7 @@ env:
) || ) ||
github.event.before github.event.before
}} }}
shouldRunParallel: ${{ secrets.CYPRESS_RECORD_KEY != '' && !(github.event_name == 'push' && github.ref == 'refs/heads/develop') }}
jobs: jobs:
cache: cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -38,7 +33,7 @@ jobs:
options: --user 1001 options: --user 1001
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
@@ -72,16 +67,6 @@ jobs:
mkdir -p cypress/snapshots/stats/base mkdir -p cypress/snapshots/stats/base
mv stats cypress/snapshots/stats/base mv stats cypress/snapshots/stats/base
- name: Cypress run
uses: cypress-io/github-action@v6
id: cypress-snapshot-gen
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
with:
install: false
start: pnpm run dev
wait-on: 'http://localhost:9000'
browser: chrome
e2e: e2e:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
@@ -95,7 +80,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js
@@ -132,7 +117,7 @@ jobs:
id: cypress id: cypress
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers # If CYPRESS_RECORD_KEY is set, run in parallel on all containers
# Otherwise (e.g. if running from fork), we run on a single container only # Otherwise (e.g. if running from fork), we run on a single container only
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }} if: ${{ env.shouldRunParallel == 'true' || ( matrix.containers == 1 ) }}
with: with:
install: false install: false
start: pnpm run dev:coverage start: pnpm run dev:coverage
@@ -140,12 +125,16 @@ jobs:
browser: chrome browser: chrome
# Disable recording if we don't have an API key # Disable recording if we don't have an API key
# e.g. if this action was run from a fork # e.g. if this action was run from a fork
record: ${{ secrets.CYPRESS_RECORD_KEY != '' }} record: ${{ env.shouldRunParallel == 'true' }}
parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }} parallel: ${{ env.shouldRunParallel == 'true' }}
env: env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
VITEST_COVERAGE: true VITEST_COVERAGE: true
CYPRESS_COMMIT: ${{ github.sha }} CYPRESS_COMMIT: ${{ github.sha }}
ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }}
ARGOS_PARALLEL: ${{ env.shouldRunParallel == 'true' }}
ARGOS_PARALLEL_TOTAL: 4
ARGOS_PARALLEL_INDEX: ${{ matrix.containers }}
- name: Upload Coverage to Codecov - name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
@@ -158,55 +147,3 @@ jobs:
fail_ci_if_error: false fail_ci_if_error: false
verbose: true verbose: true
token: 6845cc80-77ee-4e17-85a1-026cd95e0766 token: 6845cc80-77ee-4e17-85a1-026cd95e0766
# We upload the artifacts into numbered archives to prevent overwriting
- name: Upload Artifacts
uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: snapshots-${{ matrix.containers }}
retention-days: 1
path: ./cypress/snapshots
combineArtifacts:
needs: e2e
runs-on: ubuntu-latest
if: ${{ always() }}
steps:
# Download all snapshot artifacts and merge them into a single folder
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: snapshots
pattern: snapshots-*
merge-multiple: true
# For successful push events, we save the snapshots cache
- name: Save snapshots cache
id: cache-upload
if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }}
uses: actions/cache/save@v4
with:
path: ./snapshots
key: ${{ runner.os }}-snapshots-${{ github.event.after }}
- name: Flatten images to a folder
if: ${{ needs.e2e.result == 'failure' }}
run: |
mkdir errors
cd snapshots
find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \;
- name: Upload Error snapshots
if: ${{ needs.e2e.result == 'failure' }}
uses: actions/upload-artifact@v4
id: upload-artifacts
with:
name: error-snapshots
retention-days: 10
path: errors/
- name: Notify Users
if: ${{ needs.e2e.result == 'failure' }}
run: |
echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}"

View File

@@ -19,7 +19,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js

View File

@@ -25,7 +25,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@@ -13,7 +13,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: fregante/setup-git-user@v2 - uses: fregante/setup-git-user@v2
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js

View File

@@ -11,7 +11,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
# uses version from "packageManager" field in package.json # uses version from "packageManager" field in package.json
- name: Setup Node.js - name: Setup Node.js

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v4
- run: npx update-browserslist-db@latest - run: npx update-browserslist-db@latest
- name: Commit changes - name: Commit changes
uses: EndBug/add-and-commit@v9 uses: EndBug/add-and-commit@v9

3
.gitignore vendored
View File

@@ -48,6 +48,7 @@ demos/dev/**
!/demos/dev/example.html !/demos/dev/example.html
!/demos/dev/reload.js !/demos/dev/reload.js
tsx-0/** tsx-0/**
vite.config.ts.timestamp-*
# autogenereated by langium-cli # autogenereated by langium-cli
generated/ generated/

View File

@@ -1,4 +1,5 @@
import { build, InlineConfig, type PluginOption } from 'vite'; import type { InlineConfig } from 'vite';
import { build, type PluginOption } from 'vite';
import { resolve } from 'path'; import { resolve } from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import jisonPlugin from './jisonPlugin.js'; import jisonPlugin from './jisonPlugin.js';
@@ -46,9 +47,10 @@ interface BuildOptions {
export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => { export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => {
const external: (string | RegExp)[] = ['require', 'fs', 'path']; const external: (string | RegExp)[] = ['require', 'fs', 'path'];
// eslint-disable-next-line no-console
console.log(entryName, packageOptions[entryName]); console.log(entryName, packageOptions[entryName]);
const { name, file, packageName } = packageOptions[entryName]; const { name, file, packageName } = packageOptions[entryName];
let output: OutputOptions = [ const output: OutputOptions = [
{ {
name, name,
format: 'esm', format: 'esm',
@@ -83,7 +85,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
plugins: [ plugins: [
jisonPlugin(), jisonPlugin(),
jsonSchemaPlugin(), // handles `.schema.yaml` files jsonSchemaPlugin(), // handles `.schema.yaml` files
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
typescript({ compilerOptions: { declaration: false } }), typescript({ compilerOptions: { declaration: false } }),
istanbul({ istanbul({
exclude: ['node_modules', 'test/', '__mocks__', 'generated'], exclude: ['node_modules', 'test/', '__mocks__', 'generated'],
@@ -121,10 +122,10 @@ await generateLangium();
if (watch) { if (watch) {
await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' })); void build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
if (!mermaidOnly) { if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' })); void build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' }));
} }
} else if (visualize) { } else if (visualize) {
await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' })); await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));

View File

@@ -1,4 +1,4 @@
import { PluginOption } from 'vite'; import type { PluginOption } from 'vite';
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js'; import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
/** /**

View File

@@ -23,8 +23,9 @@ async function createServer() {
app.use(express.static('cypress/platform')); app.use(express.static('cypress/platform'));
app.listen(9000, () => { app.listen(9000, () => {
// eslint-disable-next-line no-console
console.log(`Listening on http://localhost:9000`); console.log(`Listening on http://localhost:9000`);
}); });
} }
createServer(); void createServer();

7
FUNDING.json Normal file
View File

@@ -0,0 +1,7 @@
{
"drips": {
"ethereum": {
"ownedBy": "0x0831DDFe60d009d9448CC976157b539089aB821E"
}
}
}

View File

@@ -35,6 +35,7 @@ Try Live Editor previews of future releases: <a href="https://develop.git.mermai
[![NPM Downloads](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![NPM Downloads](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid)
[![Join our Discord!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=discord&label=discord)](https://discord.gg/AgrbSrBer3) [![Join our Discord!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=discord&label=discord)](https://discord.gg/AgrbSrBer3)
[![Twitter Follow](https://img.shields.io/badge/Social-mermaidjs__-blue?style=social&logo=X)](https://twitter.com/mermaidjs_) [![Twitter Follow](https://img.shields.io/badge/Social-mermaidjs__-blue?style=social&logo=X)](https://twitter.com/mermaidjs_)
[![Covered by Argos Visual Testing](https://argos-ci.com/badge.svg)](https://argos-ci.com)
<img src="./img/header.png" alt="" /> <img src="./img/header.png" alt="" />

View File

@@ -2,6 +2,8 @@ import { defineConfig } from 'cypress';
import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin';
import coverage from '@cypress/code-coverage/task'; import coverage from '@cypress/code-coverage/task';
import eyesPlugin from '@applitools/eyes-cypress'; import eyesPlugin from '@applitools/eyes-cypress';
import { registerArgosTask } from '@argos-ci/cypress/task';
export default eyesPlugin( export default eyesPlugin(
defineConfig({ defineConfig({
projectId: 'n2sma2', projectId: 'n2sma2',
@@ -17,10 +19,17 @@ export default eyesPlugin(
} }
return launchOptions; return launchOptions;
}); });
addMatchImageSnapshotPlugin(on, config);
// copy any needed variables from process.env to config.env // copy any needed variables from process.env to config.env
config.env.useAppli = process.env.USE_APPLI ? true : false; config.env.useAppli = process.env.USE_APPLI ? true : false;
config.env.useArgos = !!process.env.CI;
if (config.env.useArgos) {
registerArgosTask(on, config, {
token: 'fc3a35cf5200db928d65b2047861582d9444032b',
});
} else {
addMatchImageSnapshotPlugin(on, config);
}
// do not forget to return the changed config object! // do not forget to return the changed config object!
return config; return config;
}, },

View File

@@ -35,7 +35,7 @@ export const mermaidUrl = (
}; };
const objStr: string = JSON.stringify(codeObject); const objStr: string = JSON.stringify(codeObject);
let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`; 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}`; url = `http://localhost:9000/xss.html?graph=${graphStr}`;
} }
@@ -54,16 +54,15 @@ export const imgSnapshotTest = (
): void => { ): void => {
const options: CypressMermaidConfig = { const options: CypressMermaidConfig = {
..._options, ..._options,
fontFamily: _options.fontFamily || 'courier', fontFamily: _options.fontFamily ?? 'courier',
// @ts-ignore TODO: Fix type of fontSize // @ts-ignore TODO: Fix type of fontSize
fontSize: _options.fontSize || '16px', fontSize: _options.fontSize ?? '16px',
sequence: { sequence: {
...(_options.sequence || {}), ...(_options.sequence ?? {}),
actorFontFamily: 'courier', actorFontFamily: 'courier',
noteFontFamily: noteFontFamily: _options.sequence?.noteFontFamily
_options.sequence && _options.sequence.noteFontFamily ? _options.sequence.noteFontFamily
? _options.sequence.noteFontFamily : 'courier',
: 'courier',
messageFontFamily: 'courier', messageFontFamily: 'courier',
}, },
}; };
@@ -95,18 +94,7 @@ export const openURLAndVerifyRendering = (
options: CypressMermaidConfig, options: CypressMermaidConfig,
validation?: any validation?: any
): void => { ): void => {
const useAppli: boolean = Cypress.env('useAppli'); const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
if (useAppli) {
cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
batchName: Cypress.spec.name,
batchId: batchId + Cypress.spec.name,
});
}
cy.visit(url); cy.visit(url);
cy.window().should('have.property', 'rendered', true); cy.window().should('have.property', 'rendered', true);
@@ -116,11 +104,29 @@ export const openURLAndVerifyRendering = (
cy.get('svg').should(validation); cy.get('svg').should(validation);
} }
verifyScreenshot(name);
};
export const verifyScreenshot = (name: string): void => {
const useAppli: boolean = Cypress.env('useAppli');
const useArgos: boolean = Cypress.env('useArgos');
if (useAppli) { if (useAppli) {
cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
batchName: Cypress.spec.name,
batchId: batchId + Cypress.spec.name,
});
cy.log(`Check eyes ${Cypress.spec.name}`); cy.log(`Check eyes ${Cypress.spec.name}`);
cy.eyesCheckWindow('Click!'); cy.eyesCheckWindow('Click!');
cy.log(`Closing eyes ${Cypress.spec.name}`); cy.log(`Closing eyes ${Cypress.spec.name}`);
cy.eyesClose(); cy.eyesClose();
} else if (useArgos) {
cy.argosScreenshot(name, {
threshold: 0.01,
});
} else { } else {
cy.matchImageSnapshot(name); cy.matchImageSnapshot(name);
} }

View File

@@ -1,4 +1,4 @@
import { renderGraph } from '../../helpers/util.ts'; import { renderGraph, verifyScreenshot } from '../../helpers/util.ts';
describe('Configuration', () => { describe('Configuration', () => {
describe('arrowMarkerAbsolute', () => { describe('arrowMarkerAbsolute', () => {
it('should handle default value false of arrowMarkerAbsolute', () => { it('should handle default value false of arrowMarkerAbsolute', () => {
@@ -119,8 +119,7 @@ describe('Configuration', () => {
const url = 'http://localhost:9000/regression/issue-1874.html'; const url = 'http://localhost:9000/regression/issue-1874.html';
cy.visit(url); cy.visit(url);
cy.window().should('have.property', 'rendered', true); cy.window().should('have.property', 'rendered', true);
cy.get('svg').should('be.visible'); verifyScreenshot(
cy.matchImageSnapshot(
'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives' 'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives'
); );
}); });
@@ -145,7 +144,7 @@ describe('Configuration', () => {
// none of the diagrams should be error diagrams // none of the diagrams should be error diagrams
expect($svg).to.not.contain('Syntax error'); expect($svg).to.not.contain('Syntax error');
}); });
cy.matchImageSnapshot( verifyScreenshot(
'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set' 'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set'
); );
}); });
@@ -162,7 +161,7 @@ describe('Configuration', () => {
// some of the diagrams should be error diagrams // some of the diagrams should be error diagrams
expect($svg).to.contain('Syntax error'); expect($svg).to.contain('Syntax error');
}); });
cy.matchImageSnapshot( verifyScreenshot(
'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set' 'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set'
); );
}); });

View File

@@ -10,7 +10,6 @@ describe('XSS', () => {
cy.wait(1000).then(() => { cy.wait(1000).then(() => {
cy.get('.mermaid').should('exist'); cy.get('.mermaid').should('exist');
}); });
cy.get('svg');
}); });
it('should not allow tags in the css', () => { it('should not allow tags in the css', () => {
@@ -137,4 +136,9 @@ describe('XSS', () => {
cy.wait(1000); cy.wait(1000);
cy.get('#the-malware').should('not.exist'); cy.get('#the-malware').should('not.exist');
}); });
it('should sanitize backticks block diagram labels properly', () => {
cy.visit('http://localhost:9000/xss25.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
});
}); });

View File

@@ -30,7 +30,6 @@ describe('C4 diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render a simple C4Container diagram', () => { it('should render a simple C4Container diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -50,7 +49,6 @@ describe('C4 diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render a simple C4Component diagram', () => { it('should render a simple C4Component diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -69,7 +67,6 @@ describe('C4 diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render a simple C4Dynamic diagram', () => { it('should render a simple C4Dynamic diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -93,7 +90,6 @@ describe('C4 diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render a simple C4Deployment diagram', () => { it('should render a simple C4Deployment diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -117,6 +113,5 @@ describe('C4 diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
}); });

View File

@@ -32,7 +32,6 @@ describe('Class diagram', () => {
`, `,
{ logLevel: 1 } { logLevel: 1 }
); );
cy.get('svg');
}); });
it('2: should render a simple class diagrams with cardinality', () => { it('2: should render a simple class diagrams with cardinality', () => {
@@ -61,7 +60,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('3: should render a simple class diagram with different visibilities', () => { it('3: should render a simple class diagram with different visibilities', () => {
@@ -79,7 +77,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('4: should render a simple class diagram with comments', () => { it('4: should render a simple class diagram with comments', () => {
@@ -109,7 +106,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('5: should render a simple class diagram with abstract method', () => { it('5: should render a simple class diagram with abstract method', () => {
@@ -121,7 +117,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('6: should render a simple class diagram with static method', () => { it('6: should render a simple class diagram with static method', () => {
@@ -133,7 +128,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('7: should render a simple class diagram with Generic class', () => { it('7: should render a simple class diagram with Generic class', () => {
@@ -153,7 +147,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('8: should render a simple class diagram with Generic class and relations', () => { it('8: should render a simple class diagram with Generic class and relations', () => {
@@ -174,7 +167,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('9: should render a simple class diagram with clickable link', () => { it('9: should render a simple class diagram with clickable link', () => {
@@ -196,7 +188,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('10: should render a simple class diagram with clickable callback', () => { it('10: should render a simple class diagram with clickable callback', () => {
@@ -218,7 +209,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('11: should render a simple class diagram with return type on method', () => { it('11: should render a simple class diagram with return type on method', () => {
@@ -233,7 +223,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('12: should render a simple class diagram with generic types', () => { it('12: should render a simple class diagram with generic types', () => {
@@ -249,7 +238,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('13: should render a simple class diagram with css classes applied', () => { it('13: should render a simple class diagram with css classes applied', () => {
@@ -267,7 +255,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('14: should render a simple class diagram with css classes applied directly', () => { it('14: should render a simple class diagram with css classes applied directly', () => {
@@ -283,7 +270,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('15: should render a simple class diagram with css classes applied to multiple classes', () => { it('15: should render a simple class diagram with css classes applied to multiple classes', () => {
@@ -298,7 +284,6 @@ describe('Class diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('16: should render multiple class diagrams', () => { it('16: should render multiple class diagrams', () => {
@@ -351,7 +336,6 @@ describe('Class diagram', () => {
], ],
{} {}
); );
cy.get('svg');
}); });
// it('17: should render a class diagram when useMaxWidth is true (default)', () => { // it('17: should render a class diagram when useMaxWidth is true (default)', () => {
@@ -421,7 +405,6 @@ describe('Class diagram', () => {
`, `,
{ logLevel: 1 } { logLevel: 1 }
); );
cy.get('svg');
}); });
it('should render class diagram with newlines in title', () => { it('should render class diagram with newlines in title', () => {
@@ -439,7 +422,6 @@ describe('Class diagram', () => {
+quack() +quack()
} }
`); `);
cy.get('svg');
}); });
it('should render class diagram with many newlines in title', () => { it('should render class diagram with many newlines in title', () => {

View File

@@ -218,7 +218,6 @@ describe('Entity Relationship Diagram', () => {
`, `,
{ loglevel: 1 } { loglevel: 1 }
); );
cy.get('svg');
}); });
it('should render entities with keys', () => { it('should render entities with keys', () => {

View File

@@ -10,6 +10,15 @@ describe('packet structure', () => {
); );
}); });
it('should render a simple packet diagram without ranges', () => {
imgSnapshotTest(
`packet-beta
0: "h"
1: "i"
`
);
});
it('should render a complex packet diagram', () => { it('should render a complex packet diagram', () => {
imgSnapshotTest( imgSnapshotTest(
`packet-beta `packet-beta

View File

@@ -8,7 +8,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render a complete quadrant chart', () => { it('should render a complete quadrant chart', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -30,7 +29,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render without points', () => { it('should render without points', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -46,7 +44,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should able to render y-axix on right side', () => { it('should able to render y-axix on right side', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -63,7 +60,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should able to render x-axix on bottom', () => { it('should able to render x-axix on bottom', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -80,7 +76,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should able to render x-axix on bottom and y-axis on right', () => { it('should able to render x-axix on bottom and y-axis on right', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -97,7 +92,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render without title', () => { it('should render without title', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -112,7 +106,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should use all the config', () => { it('should use all the config', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -135,7 +128,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should use all the theme variable', () => { it('should use all the theme variable', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -158,7 +150,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render x-axis labels in the center, if x-axis has two labels', () => { it('should render x-axis labels in the center, if x-axis has two labels', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -180,7 +171,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render y-axis labels in the center, if y-axis has two labels', () => { it('should render y-axis labels in the center, if y-axis has two labels', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -202,7 +192,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should render both axes labels on the left and bottom, if both axes have only one label', () => { it('should render both axes labels on the left and bottom, if both axes have only one label', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -224,7 +213,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('it should render data points with styles', () => { it('it should render data points with styles', () => {
@@ -249,7 +237,6 @@ describe('Quadrant Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('it should render data points with styles + classes', () => { it('it should render data points with styles + classes', () => {

View File

@@ -44,6 +44,5 @@ describe('Requirement diagram', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
}); });

View File

@@ -1,8 +1,6 @@
/// <reference types="Cypress" />
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
context('Sequence diagram', () => { describe('Sequence diagram', () => {
it('should render a sequence diagram with boxes', () => { it('should render a sequence diagram with boxes', () => {
renderGraph( renderGraph(
` `
@@ -68,6 +66,19 @@ context('Sequence diagram', () => {
{ sequence: { actorFontFamily: 'courier' } } { sequence: { actorFontFamily: 'courier' } }
); );
}); });
it('should render bidirectional arrows', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice<<->>John: Hello John, how are you?
Alice<<-->>John: Hi Alice, I can hear you!
John<<->>Alice: This also works the other way
John<<-->>Alice: Yes
Alice->John: Test
John->>Alice: Still works
`
);
});
it('should handle different line breaks', () => { it('should handle different line breaks', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -231,7 +242,7 @@ context('Sequence diagram', () => {
` `
); );
}); });
context('font settings', () => { describe('font settings', () => {
it('should render different note fonts when configured', () => { it('should render different note fonts when configured', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -328,7 +339,7 @@ context('Sequence diagram', () => {
); );
}); });
}); });
context('auth width scaling', () => { describe('auth width scaling', () => {
it('should render long actor descriptions', () => { it('should render long actor descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -464,6 +475,18 @@ context('Sequence diagram', () => {
{} {}
); );
}); });
it('should render notes over actors and participant', () => {
imgSnapshotTest(
`
sequenceDiagram
actor Alice
participant Charlie
note over Alice: some note
note over Charlie: other note
`,
{}
);
});
it('should render long messages from an actor to the left to one to the right', () => { it('should render long messages from an actor to the left to one to the right', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -505,7 +528,7 @@ context('Sequence diagram', () => {
); );
}); });
}); });
context('background rects', () => { describe('background rects', () => {
it('should render a single and nested rects', () => { it('should render a single and nested rects', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -785,7 +808,7 @@ context('Sequence diagram', () => {
); );
}); });
}); });
context('directives', () => { describe('directives', () => {
it('should override config with directive settings', () => { it('should override config with directive settings', () => {
imgSnapshotTest( imgSnapshotTest(
` `
@@ -817,7 +840,7 @@ context('Sequence diagram', () => {
); );
}); });
}); });
context('links', () => { describe('links', () => {
it('should support actor links', () => { it('should support actor links', () => {
renderGraph( renderGraph(
` `
@@ -833,7 +856,7 @@ context('Sequence diagram', () => {
); );
cy.get('#actor0_popup').should((popupMenu) => { cy.get('#actor0_popup').should((popupMenu) => {
const style = popupMenu.attr('style'); const style = popupMenu.attr('style');
expect(style).to.undefined; // expect(style).to.undefined;
}); });
cy.get('#root-0').click(); cy.get('#root-0').click();
cy.get('#actor0_popup').should((popupMenu) => { cy.get('#actor0_popup').should((popupMenu) => {
@@ -908,7 +931,7 @@ context('Sequence diagram', () => {
); );
}); });
}); });
context('svg size', () => { describe('svg size', () => {
it('should render a sequence diagram when useMaxWidth is true (default)', () => { it('should render a sequence diagram when useMaxWidth is true (default)', () => {
renderGraph( renderGraph(
` `
@@ -987,7 +1010,7 @@ context('Sequence diagram', () => {
}); });
}); });
}); });
context('render after error', () => { describe('render after error', () => {
it('should render diagram after fixing destroy participant error', () => { it('should render diagram after fixing destroy participant error', () => {
cy.on('uncaught:exception', (err) => { cy.on('uncaught:exception', (err) => {
return false; return false;

View File

@@ -8,7 +8,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 1, fontFamily: 'courier' } { logLevel: 1, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a simple state diagrams', () => { it('v2 should render a simple state diagrams', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -20,7 +19,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a long descriptions instead of id when available', () => { it('v2 should render a long descriptions instead of id when available', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -32,7 +30,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a long descriptions with additional descriptions', () => { it('v2 should render a long descriptions with additional descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -44,7 +41,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a single state with short descriptions', () => { it('v2 should render a single state with short descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -55,7 +51,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a transition descriptions with new lines', () => { it('v2 should render a transition descriptions with new lines', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -69,7 +64,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a state with a note', () => { it('v2 should render a state with a note', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -83,7 +77,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a state with on the left side when so specified', () => { it('v2 should render a state with on the left side when so specified', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -97,7 +90,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a state with a note together with another state', () => { it('v2 should render a state with a note together with another state', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -113,7 +105,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a note with multiple lines in it', () => { it('v2 should render a note with multiple lines in it', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -156,7 +147,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a simple state diagrams 2', () => { it('v2 should render a simple state diagrams 2', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -169,7 +159,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a simple state diagrams with labels', () => { it('v2 should render a simple state diagrams with labels', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -185,7 +174,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render state descriptions', () => { it('v2 should render state descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -198,7 +186,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render composite states', () => { it('v2 should render composite states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -217,7 +204,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render multiple composite states', () => { it('v2 should render multiple composite states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -287,7 +273,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render concurrency states', () => { it('v2 should render concurrency states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -311,7 +296,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('v2 should render a state with states in it', () => { it('v2 should render a state with states in it', () => {
imgSnapshotTest( imgSnapshotTest(

View File

@@ -10,7 +10,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a long descriptions instead of id when available', () => { it('should render a long descriptions instead of id when available', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -22,7 +21,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a long descriptions with additional descriptions', () => { it('should render a long descriptions with additional descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -34,7 +32,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a single state with short descriptions', () => { it('should render a single state with short descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -45,7 +42,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a transition descriptions with new lines', () => { it('should render a transition descriptions with new lines', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -59,7 +55,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a state with a note', () => { it('should render a state with a note', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -73,7 +68,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a state with on the left side when so specified', () => { it('should render a state with on the left side when so specified', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -87,7 +81,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a state with a note together with another state', () => { it('should render a state with a note together with another state', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -103,7 +96,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a note with multiple lines in it', () => { it('should render a note with multiple lines in it', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -146,7 +138,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a simple state diagrams 2', () => { it('should render a simple state diagrams 2', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -159,7 +150,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a simple state diagrams with labels', () => { it('should render a simple state diagrams with labels', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -175,7 +165,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render state descriptions', () => { it('should render state descriptions', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -188,7 +177,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render composite states', () => { it('should render composite states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -207,7 +195,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render multiple composit states', () => { it('should render multiple composit states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -277,7 +264,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render concurrency states', () => { it('should render concurrency states', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -301,7 +287,6 @@ describe('State diagram', () => {
`, `,
{ logLevel: 0, fontFamily: 'courier' } { logLevel: 0, fontFamily: 'courier' }
); );
cy.get('svg');
}); });
it('should render a state with states in it', () => { it('should render a state with states in it', () => {
imgSnapshotTest( imgSnapshotTest(

View File

@@ -10,7 +10,6 @@ describe('themeCSS balancing, it', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('should not allow unbalanced CSS definitions 2', () => { it('should not allow unbalanced CSS definitions 2', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -21,7 +20,6 @@ describe('themeCSS balancing, it', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
}); });
@@ -45,7 +43,6 @@ describe('Pie Chart', () => {
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a flowchart diagram', () => { it('should render a flowchart diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -70,7 +67,6 @@ describe('Pie Chart', () => {
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a new flowchart diagram', () => { it('should render a new flowchart diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -96,7 +92,6 @@ describe('Pie Chart', () => {
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a sequence diagram', () => { it('should render a sequence diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -125,7 +120,6 @@ describe('Pie Chart', () => {
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a class diagram', () => { it('should render a class diagram', () => {
@@ -175,7 +169,6 @@ describe('Pie Chart', () => {
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a state diagram', () => { it('should render a state diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -210,7 +203,6 @@ stateDiagram
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a state diagram (v2)', () => { it('should render a state diagram (v2)', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -245,7 +237,6 @@ stateDiagram-v2
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a er diagram', () => { it('should render a er diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -266,7 +257,6 @@ erDiagram
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a user journey diagram', () => { it('should render a user journey diagram', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -287,7 +277,6 @@ erDiagram
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
it('should render a gantt diagram', () => { it('should render a gantt diagram', () => {
cy.clock(new Date('2014-01-06').getTime()); cy.clock(new Date('2014-01-06').getTime());
@@ -326,7 +315,6 @@ erDiagram
`, `,
{ theme } { theme }
); );
cy.get('svg');
}); });
}); });
}); });

View File

@@ -9,7 +9,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Should render a complete chart', () => { it('Should render a complete chart', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -35,7 +34,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('y-axis title not required', () => { it('y-axis title not required', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -48,7 +46,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Should render a chart without y-axis with different range', () => { it('Should render a chart without y-axis with different range', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -60,7 +57,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('x axis title not required', () => { it('x axis title not required', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -72,7 +68,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Multiple plots can be rendered', () => { it('Multiple plots can be rendered', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -87,7 +82,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Decimals and negative numbers are supported', () => { it('Decimals and negative numbers are supported', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -98,7 +92,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render spark line with "plotReservedSpacePercent"', () => { it('Render spark line with "plotReservedSpacePercent"', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -116,7 +109,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render spark bar without displaying other property', () => { it('Render spark bar without displaying other property', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -143,7 +135,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Should use all the config from directive', () => { it('Should use all the config from directive', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -158,7 +149,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Should use all the config from yaml', () => { it('Should use all the config from yaml', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -199,7 +189,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render with show axis title false', () => { it('Render with show axis title false', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -221,7 +210,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render with show axis label false', () => { it('Render with show axis label false', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -243,7 +231,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render with show axis tick false', () => { it('Render with show axis tick false', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -265,7 +252,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render with show axis line false', () => { it('Render with show axis line false', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -287,7 +273,6 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
cy.get('svg');
}); });
it('Render all the theme color', () => { it('Render all the theme color', () => {
imgSnapshotTest( imgSnapshotTest(
@@ -317,6 +302,17 @@ describe('XY Chart', () => {
`, `,
{} {}
); );
});
it('should use the correct distances between data points', () => {
imgSnapshotTest(
`
xychart-beta
x-axis 0 --> 2
line [0, 1, 0, 1]
bar [1, 0, 1, 0]
`,
{}
);
cy.get('svg'); cy.get('svg');
}); });
}); });

View File

@@ -27,7 +27,7 @@ const code3 = `flowchart TD
A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />) A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />)
B(<b>Bold text!</b>)`; B(<b>Bold text!</b>)`;
if (location.href.match('test-html-escaping')) { if (/test-html-escaping/.exec(location.href)) {
code = code3; code = code3;
} }

View File

@@ -132,7 +132,7 @@ if (typeof document !== 'undefined') {
window.addEventListener( window.addEventListener(
'load', 'load',
function () { function () {
if (this.location.href.match('xss.html')) { if (/xss.html/.exec(this.location.href)) {
this.console.log('Using api'); this.console.log('Using api');
void contentLoadedApi().finally(markRendered); void contentLoadedApi().finally(markRendered);
} else { } else {

108
cypress/platform/xss25.html Normal file
View File

@@ -0,0 +1,108 @@
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
rel="stylesheet"
/>
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 {
color: grey;
}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
<script>
function xssAttack() {
const div = document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeeded');
}
</script>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
</div>
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-wrapper',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10,
curve: 'cardinal',
htmlLabels: true,
},
htmlLabels: false,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'strict',
startOnLoad: false,
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
// themeVariables: {relationLabelColor: 'red'}
});
function callback() {
alert('It worked');
}
let diagram = 'block-beta\n';
diagram += '`A-- "X<img src=x on';
diagram += 'error=xssAttack()>" -->B';
console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
const { svg } = await mermaid.render('diagram', diagram);
document.querySelector('#res').innerHTML = svg;
</script>
</body>
</html>

View File

@@ -15,6 +15,7 @@
import '@cypress/code-coverage/support'; import '@cypress/code-coverage/support';
import '@applitools/eyes-cypress/commands'; import '@applitools/eyes-cypress/commands';
import '@argos-ci/cypress/support';
// Import commands.js using ES2015 syntax: // Import commands.js using ES2015 syntax:
import './commands'; import './commands';

View File

@@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"target": "es2020", "target": "es2020",
"lib": ["es2020", "dom"], "lib": ["es2020", "dom"],
"types": ["cypress", "node"], "types": ["cypress", "node", "@argos-ci/cypress/dist/support.d.ts"],
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"noEmit": true "noEmit": true
}, },

View File

@@ -238,6 +238,17 @@
Alice-xJohn: Hello John, how are you? Alice-xJohn: Hello John, how are you?
John--xAlice: Great! John--xAlice: Great!
</pre> </pre>
<hr />
<pre class="mermaid">
sequenceDiagram
participant Alice
participant Bob
Alice<<->>Bob: Hello!
Alice<<->>Bob: Wow, we said that at the same time!
Bob<<-->>Alice: Bidirectional Arrows are so cool
</pre>
<script type="module"> <script type="module">
import mermaid from './mermaid.esm.mjs'; import mermaid from './mermaid.esm.mjs';
mermaid.initialize({ mermaid.initialize({

View File

@@ -1,4 +1,3 @@
version: '3.9'
services: services:
mermaid: mermaid:
build: build:
@@ -8,7 +7,7 @@ services:
tty: true tty: true
working_dir: /mermaid working_dir: /mermaid
mem_limit: '8G' mem_limit: '8G'
entrypoint: docker-entrypoint.sh entrypoint: ./docker-entrypoint.sh
environment: environment:
- NODE_OPTIONS=--max_old_space_size=8192 - NODE_OPTIONS=--max_old_space_size=8192
volumes: volumes:
@@ -16,6 +15,7 @@ services:
- root_cache:/root/.cache - root_cache:/root/.cache
- root_local:/root/.local - root_local:/root/.local
- root_npm:/root/.npm - root_npm:/root/.npm
- /tmp:/tmp
ports: ports:
- 9000:9000 - 9000:9000
- 3333:3333 - 3333:3333

View File

@@ -56,7 +56,7 @@ The following commands must be sufficient enough to start with:
```bash ```bash
curl -fsSL https://get.pnpm.io/install.sh | sh - curl -fsSL https://get.pnpm.io/install.sh | sh -
pnpm env use --global 18 pnpm env use --global 20
``` ```
You may also need to reload `.shrc` or `.bashrc` afterwards. You may also need to reload `.shrc` or `.bashrc` afterwards.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -84,3 +84,13 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b
</body> </body>
</html> </html>
``` ```
## Handling Rendering Differences
Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config.
This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set.
If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below).
![Image showing differences between Browsers](img/mathMLDifferences.png)

View File

@@ -10,4 +10,4 @@
- [config](modules/config.md) - [config](modules/config.md)
- [defaultConfig](modules/defaultConfig.md) - [defaultConfig](modules/defaultConfig.md)
- [mermaidAPI](modules/mermaidAPI.md) - [mermaid](modules/mermaid.md)

View File

@@ -0,0 +1,171 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/classes/mermaid.UnknownDiagramError.md](../../../../packages/mermaid/src/docs/config/setup/classes/mermaid.UnknownDiagramError.md).
# Class: UnknownDiagramError
[mermaid](../modules/mermaid.md).UnknownDiagramError
## Hierarchy
- `Error`
**`UnknownDiagramError`**
## Constructors
### constructor
**new UnknownDiagramError**(`message`): [`UnknownDiagramError`](mermaid.UnknownDiagramError.md)
#### Parameters
| Name | Type |
| :-------- | :------- |
| `message` | `string` |
#### Returns
[`UnknownDiagramError`](mermaid.UnknownDiagramError.md)
#### Overrides
Error.constructor
#### Defined in
[packages/mermaid/src/errors.ts:2](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/errors.ts#L2)
## Properties
### cause
`Optional` **cause**: `unknown`
#### Inherited from
Error.cause
#### Defined in
node_modules/.pnpm/typescript\@5.4.5/node_modules/typescript/lib/lib.es2022.error.d.ts:24
---
### message
**message**: `string`
#### Inherited from
Error.message
#### Defined in
node_modules/.pnpm/typescript\@5.4.5/node_modules/typescript/lib/lib.es5.d.ts:1077
---
### name
**name**: `string`
#### Inherited from
Error.name
#### Defined in
node_modules/.pnpm/typescript\@5.4.5/node_modules/typescript/lib/lib.es5.d.ts:1076
---
### stack
`Optional` **stack**: `string`
#### Inherited from
Error.stack
#### Defined in
node_modules/.pnpm/typescript\@5.4.5/node_modules/typescript/lib/lib.es5.d.ts:1078
---
### prepareStackTrace
`Static` `Optional` **prepareStackTrace**: (`err`: `Error`, `stackTraces`: `CallSite`\[]) => `any`
Optional override for formatting stack traces
**`See`**
<https://v8.dev/docs/stack-trace-api#customizing-stack-traces>
#### Type declaration
▸ (`err`, `stackTraces`): `any`
##### Parameters
| Name | Type |
| :------------ | :------------ |
| `err` | `Error` |
| `stackTraces` | `CallSite`\[] |
##### Returns
`any`
#### Inherited from
Error.prepareStackTrace
#### Defined in
node_modules/@types/node/globals.d.ts:28
---
### stackTraceLimit
`Static` **stackTraceLimit**: `number`
#### Inherited from
Error.stackTraceLimit
#### Defined in
node_modules/@types/node/globals.d.ts:30
## Methods
### captureStackTrace
**captureStackTrace**(`targetObject`, `constructorOpt?`): `void`
Create .stack property on a target object
#### Parameters
| Name | Type |
| :---------------- | :--------- |
| `targetObject` | `object` |
| `constructorOpt?` | `Function` |
#### Returns
`void`
#### Inherited from
Error.captureStackTrace
#### Defined in
node_modules/@types/node/globals.d.ts:21

View File

@@ -0,0 +1,49 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.DetailedError.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.DetailedError.md).
# Interface: DetailedError
[mermaid](../modules/mermaid.md).DetailedError
## Properties
### error
`Optional` **error**: `any`
#### Defined in
[packages/mermaid/src/utils.ts:785](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L785)
---
### hash
**hash**: `any`
#### Defined in
[packages/mermaid/src/utils.ts:783](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L783)
---
### message
`Optional` **message**: `string`
#### Defined in
[packages/mermaid/src/utils.ts:786](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L786)
---
### str
**str**: `string`
#### Defined in
[packages/mermaid/src/utils.ts:781](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L781)

View File

@@ -0,0 +1,39 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.ExternalDiagramDefinition.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.ExternalDiagramDefinition.md).
# Interface: ExternalDiagramDefinition
[mermaid](../modules/mermaid.md).ExternalDiagramDefinition
## Properties
### detector
**detector**: `DiagramDetector`
#### Defined in
[packages/mermaid/src/diagram-api/types.ts:101](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L101)
---
### id
**id**: `string`
#### Defined in
[packages/mermaid/src/diagram-api/types.ts:100](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L100)
---
### loader
**loader**: `DiagramLoader`
#### Defined in
[packages/mermaid/src/diagram-api/types.ts:102](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L102)

View File

@@ -0,0 +1,340 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.Mermaid.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.Mermaid.md).
# Interface: Mermaid
[mermaid](../modules/mermaid.md).Mermaid
## Properties
### contentLoaded
**contentLoaded**: () => `void`
#### Type declaration
▸ (): `void`
\##contentLoaded Callback function that is called when page is loaded. This functions fetches
configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
page.
##### Returns
`void`
#### Defined in
[packages/mermaid/src/mermaid.ts:425](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L425)
---
### detectType
**detectType**: (`text`: `string`, `config?`: [`MermaidConfig`](mermaid.MermaidConfig.md)) => `string`
#### Type declaration
▸ (`text`, `config?`): `string`
Detects the type of the graph text.
Takes into consideration the possible existence of an `%%init` directive
##### Parameters
| Name | Type | Description |
| :-------- | :------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `text` | `string` | The text defining the graph. For example: `mermaid %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%% graph LR a-->b b-->c c-->d d-->e e-->f f-->g g-->h ` |
| `config?` | [`MermaidConfig`](mermaid.MermaidConfig.md) | The mermaid config. |
##### Returns
`string`
A graph definition key
#### Defined in
[packages/mermaid/src/mermaid.ts:427](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L427)
---
### init
**init**: (`config?`: [`MermaidConfig`](mermaid.MermaidConfig.md), `nodes?`: `string` | `HTMLElement` | `NodeListOf`<`HTMLElement`>, `callback?`: (`id`: `string`) => `unknown`) => `Promise`<`void`>
**`Deprecated`**
Use [initialize](mermaid.Mermaid.md#initialize) and [run](mermaid.Mermaid.md#run) instead.
#### Type declaration
▸ (`config?`, `nodes?`, `callback?`): `Promise`<`void`>
##### Parameters
| Name | Type |
| :---------- | :------------------------------------------------------- |
| `config?` | [`MermaidConfig`](mermaid.MermaidConfig.md) |
| `nodes?` | `string` \| `HTMLElement` \| `NodeListOf`<`HTMLElement`> |
| `callback?` | (`id`: `string`) => `unknown` |
##### Returns
`Promise`<`void`>
#### Defined in
[packages/mermaid/src/mermaid.ts:421](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L421)
---
### initialize
**initialize**: (`config`: [`MermaidConfig`](mermaid.MermaidConfig.md)) => `void`
#### Type declaration
▸ (`config`): `void`
Used to set configurations for mermaid.
This function should be called before the run function.
##### Parameters
| Name | Type | Description |
| :------- | :------------------------------------------ | :-------------------------------- |
| `config` | [`MermaidConfig`](mermaid.MermaidConfig.md) | Configuration object for mermaid. |
##### Returns
`void`
#### Defined in
[packages/mermaid/src/mermaid.ts:424](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L424)
---
### mermaidAPI
**mermaidAPI**: `Readonly`<{ `defaultConfig`: [`MermaidConfig`](mermaid.MermaidConfig.md) = configApi.defaultConfig; `getConfig`: () => [`MermaidConfig`](mermaid.MermaidConfig.md) = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => [`MermaidConfig`](mermaid.MermaidConfig.md) = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: [`MermaidConfig`](mermaid.MermaidConfig.md)) => `void` ; `parse`: (`text`: `string`, `parseOptions`: [`ParseOptions`](mermaid.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](mermaid.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](mermaid.ParseOptions.md)) => `Promise`<[`ParseResult`](mermaid.ParseResult.md)> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](mermaid.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: [`MermaidConfig`](mermaid.MermaidConfig.md)) => [`MermaidConfig`](mermaid.MermaidConfig.md) = configApi.setConfig; `updateSiteConfig`: (`conf`: [`MermaidConfig`](mermaid.MermaidConfig.md)) => [`MermaidConfig`](mermaid.MermaidConfig.md) = configApi.updateSiteConfig }>
**`Deprecated`**
Use [parse](mermaid.Mermaid.md#parse) and [render](mermaid.Mermaid.md#render) instead. Please [open a discussion](https://github.com/mermaid-js/mermaid/discussions) if your use case does not fit the new API.
#### Defined in
[packages/mermaid/src/mermaid.ts:415](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L415)
---
### parse
**parse**: (`text`: `string`, `parseOptions`: [`ParseOptions`](mermaid.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](mermaid.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](mermaid.ParseOptions.md)) => `Promise`<[`ParseResult`](mermaid.ParseResult.md)>
#### Type declaration
▸ (`text`, `parseOptions`): `Promise`<[`ParseResult`](mermaid.ParseResult.md) | `false`>
Parse the text and validate the syntax.
##### Parameters
| Name | Type | Description |
| :------------- | :----------------------------------------------------------------------- | :------------------------------ |
| `text` | `string` | The mermaid diagram definition. |
| `parseOptions` | [`ParseOptions`](mermaid.ParseOptions.md) & { `suppressErrors`: `true` } | Options for parsing. |
##### Returns
`Promise`<[`ParseResult`](mermaid.ParseResult.md) | `false`>
An object with the `diagramType` set to type of the diagram if valid. Otherwise `false` if parseOptions.suppressErrors is `true`.
**`See`**
[ParseOptions](mermaid.ParseOptions.md)
**`Throws`**
Error if the diagram is invalid and parseOptions.suppressErrors is false or not set.
▸ (`text`, `parseOptions?`): `Promise`<[`ParseResult`](mermaid.ParseResult.md)>
##### Parameters
| Name | Type |
| :-------------- | :---------------------------------------- |
| `text` | `string` |
| `parseOptions?` | [`ParseOptions`](mermaid.ParseOptions.md) |
##### Returns
`Promise`<[`ParseResult`](mermaid.ParseResult.md)>
#### Defined in
[packages/mermaid/src/mermaid.ts:416](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L416)
---
### parseError
`Optional` **parseError**: [`ParseErrorFunction`](../modules/mermaid.md#parseerrorfunction)
#### Defined in
[packages/mermaid/src/mermaid.ts:410](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L410)
---
### registerExternalDiagrams
**registerExternalDiagrams**: (`diagrams`: [`ExternalDiagramDefinition`](mermaid.ExternalDiagramDefinition.md)\[], `opts`: { `lazyLoad?`: `boolean` = true }) => `Promise`<`void`>
#### Type declaration
▸ (`diagrams`, `opts?`): `Promise`<`void`>
Used to register external diagram types.
##### Parameters
| Name | Type | Default value | Description |
| :--------------- | :--------------------------------------------------------------------- | :------------ | :-------------------------------------------------------------------------- |
| `diagrams` | [`ExternalDiagramDefinition`](mermaid.ExternalDiagramDefinition.md)\[] | `undefined` | Array of [ExternalDiagramDefinition](mermaid.ExternalDiagramDefinition.md). |
| `opts` | `Object` | `{}` | If opts.lazyLoad is false, the diagrams will be loaded immediately. |
| `opts.lazyLoad?` | `boolean` | `true` | - |
##### Returns
`Promise`<`void`>
#### Defined in
[packages/mermaid/src/mermaid.ts:423](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L423)
---
### render
**render**: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](mermaid.RenderResult.md)>
#### Type declaration
▸ (`id`, `text`, `svgContainingElement?`): `Promise`<[`RenderResult`](mermaid.RenderResult.md)>
##### Parameters
| Name | Type |
| :---------------------- | :-------- |
| `id` | `string` |
| `text` | `string` |
| `svgContainingElement?` | `Element` |
##### Returns
`Promise`<[`RenderResult`](mermaid.RenderResult.md)>
#### Defined in
[packages/mermaid/src/mermaid.ts:417](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L417)
---
### run
**run**: (`options`: [`RunOptions`](mermaid.RunOptions.md)) => `Promise`<`void`>
#### Type declaration
▸ (`options?`): `Promise`<`void`>
## run
Function that goes through the document to find the chart definitions in there and render them.
The function tags the processed attributes with the attribute data-processed and ignores found
elements with the attribute already set. This way the init function can be triggered several
times.
```mermaid-example
graph LR;
a(Find elements)-->b{Processed}
b-->|Yes|c(Leave element)
b-->|No |d(Transform)
```
```mermaid
graph LR;
a(Find elements)-->b{Processed}
b-->|Yes|c(Leave element)
b-->|No |d(Transform)
```
Renders the mermaid diagrams
##### Parameters
| Name | Type | Description |
| :-------- | :------------------------------------ | :----------------------- |
| `options` | [`RunOptions`](mermaid.RunOptions.md) | Optional runtime configs |
##### Returns
`Promise`<`void`>
#### Defined in
[packages/mermaid/src/mermaid.ts:422](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L422)
---
### setParseErrorHandler
• **setParseErrorHandler**: (`parseErrorHandler`: (`err`: `any`, `hash`: `any`) => `void`) => `void`
#### Type declaration
▸ (`parseErrorHandler`): `void`
## setParseErrorHandler Alternative to directly setting parseError using:
```js
mermaid.parseError = function (err, hash) {
forExampleDisplayErrorInGui(err); // do something with the error
};
```
This is provided for environments where the mermaid object can't directly have a new member added
to it (eg. dart interop wrapper). (Initially there is no parseError member of mermaid).
##### Parameters
| Name | Type | Description |
| :------------------ | :-------------------------------------- | :------------------------- |
| `parseErrorHandler` | (`err`: `any`, `hash`: `any`) => `void` | New parseError() callback. |
##### Returns
`void`
#### Defined in
[packages/mermaid/src/mermaid.ts:426](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L426)
---
### startOnLoad
• **startOnLoad**: `boolean`
#### Defined in
[packages/mermaid/src/mermaid.ts:409](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L409)

View File

@@ -0,0 +1,467 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.MermaidConfig.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.MermaidConfig.md).
# Interface: MermaidConfig
[mermaid](../modules/mermaid.md).MermaidConfig
## Properties
### altFontFamily
`Optional` **altFontFamily**: `string`
#### Defined in
[packages/mermaid/src/config.type.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L85)
---
### arrowMarkerAbsolute
`Optional` **arrowMarkerAbsolute**: `boolean`
Controls whether or arrow markers in html code are absolute paths or anchors.
This matters if you are using base tag settings.
#### Defined in
[packages/mermaid/src/config.type.ts:104](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L104)
---
### block
`Optional` **block**: `BlockDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:162](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L162)
---
### c4
`Optional` **c4**: `C4DiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:159](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L159)
---
### class
`Optional` **class**: `ClassDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:150](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L150)
---
### darkMode
`Optional` **darkMode**: `boolean`
#### Defined in
[packages/mermaid/src/config.type.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L76)
---
### deterministicIDSeed
`Optional` **deterministicIDSeed**: `string`
This option is the optional seed for deterministic ids.
If set to `undefined` but deterministicIds is `true`, a simple number iterator is used.
You can set this attribute to base the seed on a static string.
#### Defined in
[packages/mermaid/src/config.type.ts:144](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L144)
---
### deterministicIds
`Optional` **deterministicIds**: `boolean`
This option controls if the generated ids of nodes in the SVG are
generated randomly or based on a seed.
If set to `false`, the IDs are generated based on the current date and
thus are not deterministic. This is the default behavior.
This matters if your files are checked into source control e.g. git and
should not change unless content is changed.
#### Defined in
[packages/mermaid/src/config.type.ts:137](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L137)
---
### dompurifyConfig
`Optional` **dompurifyConfig**: `Config`
#### Defined in
[packages/mermaid/src/config.type.ts:163](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L163)
---
### er
`Optional` **er**: `ErDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:152](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L152)
---
### flowchart
`Optional` **flowchart**: `FlowchartDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L145)
---
### fontFamily
`Optional` **fontFamily**: `string`
Specifies the font to be used in the rendered diagrams.
Can be any possible CSS `font-family`.
See <https://developer.mozilla.org/en-US/docs/Web/CSS/font-family>
#### Defined in
[packages/mermaid/src/config.type.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L84)
---
### fontSize
`Optional` **fontSize**: `number`
#### Defined in
[packages/mermaid/src/config.type.ts:165](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L165)
---
### forceLegacyMathML
`Optional` **forceLegacyMathML**: `boolean`
This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS
fonts and browser's MathML implementation, this option is recommended if consistent rendering is important.
If set to true, ignores legacyMathML.
#### Defined in
[packages/mermaid/src/config.type.ts:126](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L126)
---
### gantt
`Optional` **gantt**: `GanttDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:147](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L147)
---
### gitGraph
`Optional` **gitGraph**: `GitGraphDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:158](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L158)
---
### htmlLabels
`Optional` **htmlLabels**: `boolean`
#### Defined in
[packages/mermaid/src/config.type.ts:77](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L77)
---
### journey
`Optional` **journey**: `JourneyDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:148](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L148)
---
### legacyMathML
`Optional` **legacyMathML**: `boolean`
This option specifies if Mermaid can expect the dependent to include KaTeX stylesheets for browsers
without their own MathML implementation. If this option is disabled and MathML is not supported, the math
equations are replaced with a warning. If this option is enabled and MathML is not supported, Mermaid will
fall back to legacy rendering for KaTeX.
#### Defined in
[packages/mermaid/src/config.type.ts:119](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L119)
---
### logLevel
`Optional` **logLevel**: `0` | `2` | `1` | `"trace"` | `"debug"` | `"info"` | `"warn"` | `"error"` | `"fatal"` | `3` | `4` | `5`
This option decides the amount of logging to be used by mermaid.
#### Defined in
[packages/mermaid/src/config.type.ts:90](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L90)
---
### markdownAutoWrap
`Optional` **markdownAutoWrap**: `boolean`
#### Defined in
[packages/mermaid/src/config.type.ts:166](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L166)
---
### maxEdges
`Optional` **maxEdges**: `number`
Defines the maximum number of edges that can be drawn in a graph.
#### Defined in
[packages/mermaid/src/config.type.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L75)
---
### maxTextSize
`Optional` **maxTextSize**: `number`
The maximum allowed size of the users text diagram
#### Defined in
[packages/mermaid/src/config.type.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L70)
---
### mindmap
`Optional` **mindmap**: `MindmapDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:157](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L157)
---
### packet
`Optional` **packet**: `PacketDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:161](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L161)
---
### pie
`Optional` **pie**: `PieDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L153)
---
### quadrantChart
`Optional` **quadrantChart**: `QuadrantChartConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L154)
---
### requirement
`Optional` **requirement**: `RequirementDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:156](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L156)
---
### sankey
`Optional` **sankey**: `SankeyDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:160](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L160)
---
### secure
`Optional` **secure**: `string`\[]
This option controls which `currentConfig` keys are considered secure and
can only be changed via call to `mermaid.initialize`.
This prevents malicious graph directives from overriding a site's default security.
#### Defined in
[packages/mermaid/src/config.type.ts:111](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L111)
---
### securityLevel
`Optional` **securityLevel**: `"strict"` | `"loose"` | `"antiscript"` | `"sandbox"`
Level of trust for parsed diagram
#### Defined in
[packages/mermaid/src/config.type.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L94)
---
### sequence
`Optional` **sequence**: `SequenceDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L146)
---
### startOnLoad
`Optional` **startOnLoad**: `boolean`
Dictates whether mermaid starts on Page load
#### Defined in
[packages/mermaid/src/config.type.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L98)
---
### state
`Optional` **state**: `StateDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:151](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L151)
---
### suppressErrorRendering
`Optional` **suppressErrorRendering**: `boolean`
Suppresses inserting 'Syntax error' diagram in the DOM.
This is useful when you want to control how to handle syntax errors in your application.
#### Defined in
[packages/mermaid/src/config.type.ts:172](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L172)
---
### theme
`Optional` **theme**: `"default"` | `"forest"` | `"dark"` | `"neutral"` | `"null"`
Theme, the CSS style sheet.
You may also use `themeCSS` to override this value.
#### Defined in
[packages/mermaid/src/config.type.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L64)
---
### themeCSS
`Optional` **themeCSS**: `string`
#### Defined in
[packages/mermaid/src/config.type.ts:66](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L66)
---
### themeVariables
`Optional` **themeVariables**: `any`
#### Defined in
[packages/mermaid/src/config.type.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L65)
---
### timeline
`Optional` **timeline**: `TimelineDiagramConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:149](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L149)
---
### wrap
`Optional` **wrap**: `boolean`
#### Defined in
[packages/mermaid/src/config.type.ts:164](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L164)
---
### xyChart
`Optional` **xyChart**: `XYChartConfig`
#### Defined in
[packages/mermaid/src/config.type.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.type.ts#L155)

View File

@@ -2,11 +2,11 @@
> >
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. > ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
> >
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md). > ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.ParseOptions.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.ParseOptions.md).
# Interface: ParseOptions # Interface: ParseOptions
[mermaidAPI](../modules/mermaidAPI.md).ParseOptions [mermaid](../modules/mermaid.md).ParseOptions
## Properties ## Properties
@@ -19,4 +19,4 @@ The `parseError` function will not be called.
#### Defined in #### Defined in
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64) [packages/mermaid/src/types.ts:43](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L43)

View File

@@ -0,0 +1,21 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.ParseResult.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.ParseResult.md).
# Interface: ParseResult
[mermaid](../modules/mermaid.md).ParseResult
## Properties
### diagramType
**diagramType**: `string`
The diagram type, e.g. 'flowchart', 'sequence', etc.
#### Defined in
[packages/mermaid/src/types.ts:50](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L50)

View File

@@ -2,11 +2,11 @@
> >
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT. > ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
> >
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.RenderResult.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.RenderResult.md). > ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.RenderResult.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.RenderResult.md).
# Interface: RenderResult # Interface: RenderResult
[mermaidAPI](../modules/mermaidAPI.md).RenderResult [mermaid](../modules/mermaid.md).RenderResult
## Properties ## Properties
@@ -18,7 +18,7 @@ Bind function to be called after the svg has been inserted into the DOM.
This is necessary for adding event listeners to the elements in the svg. This is necessary for adding event listeners to the elements in the svg.
```js ```js
const { svg, bindFunctions } = mermaidAPI.render('id1', 'graph TD;A-->B'); const { svg, bindFunctions } = await mermaid.render('id1', 'graph TD;A-->B');
div.innerHTML = svg; div.innerHTML = svg;
bindFunctions?.(div); // To call bindFunctions only if it's present. bindFunctions?.(div); // To call bindFunctions only if it's present.
``` ```
@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
#### Defined in #### Defined in
[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94) [packages/mermaid/src/types.ts:73](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L73)
--- ---
@@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
#### Defined in #### Defined in
[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84) [packages/mermaid/src/types.ts:63](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L63)
--- ---
@@ -63,4 +63,4 @@ The svg code for the rendered graph.
#### Defined in #### Defined in
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80) [packages/mermaid/src/types.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L59)

View File

@@ -0,0 +1,71 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaid.RunOptions.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaid.RunOptions.md).
# Interface: RunOptions
[mermaid](../modules/mermaid.md).RunOptions
## Properties
### nodes
`Optional` **nodes**: `ArrayLike`<`HTMLElement`>
The nodes to render. If this is set, `querySelector` will be ignored.
#### Defined in
[packages/mermaid/src/mermaid.ts:39](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L39)
---
### postRenderCallback
`Optional` **postRenderCallback**: (`id`: `string`) => `unknown`
A callback to call after each diagram is rendered.
#### Type declaration
▸ (`id`): `unknown`
##### Parameters
| Name | Type |
| :--- | :------- |
| `id` | `string` |
##### Returns
`unknown`
#### Defined in
[packages/mermaid/src/mermaid.ts:43](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L43)
---
### querySelector
`Optional` **querySelector**: `string`
The query selector to use when finding elements to render. Default: `".mermaid"`.
#### Defined in
[packages/mermaid/src/mermaid.ts:35](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L35)
---
### suppressErrors
`Optional` **suppressErrors**: `boolean`
If `true`, errors will be logged to the console, but not thrown. Default: `false`
#### Defined in
[packages/mermaid/src/mermaid.ts:47](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L47)

View File

@@ -1,21 +0,0 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseResult.md](../../../../packages/mermaid/src/docs/config/setup/interfaces/mermaidAPI.ParseResult.md).
# Interface: ParseResult
[mermaidAPI](../modules/mermaidAPI.md).ParseResult
## Properties
### diagramType
**diagramType**: `string`
The diagram type, e.g. 'flowchart', 'sequence', etc.
#### Defined in
[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71)

View File

@@ -10,11 +10,11 @@
### defaultConfig ### defaultConfig
`Const` **defaultConfig**: `MermaidConfig` `Const` **defaultConfig**: [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
#### Defined in #### Defined in
[config.ts:8](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L8) [packages/mermaid/src/config.ts:8](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L8)
## Functions ## Functions
@@ -26,9 +26,9 @@ Pushes in a directive to the configuration
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |
| :---------- | :-------------- | :----------------------- | | :---------- | :-------------------------------------------------------- | :----------------------- |
| `directive` | `MermaidConfig` | The directive to push in | | `directive` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) | The directive to push in |
#### Returns #### Returns
@@ -36,13 +36,13 @@ Pushes in a directive to the configuration
#### Defined in #### Defined in
[config.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L188) [packages/mermaid/src/config.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L188)
--- ---
### getConfig ### getConfig
**getConfig**(): `MermaidConfig` **getConfig**(): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
## getConfig ## getConfig
@@ -54,19 +54,19 @@ Pushes in a directive to the configuration
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
The currentConfig The currentConfig
#### Defined in #### Defined in
[config.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L131) [packages/mermaid/src/config.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L131)
--- ---
### getSiteConfig ### getSiteConfig
**getSiteConfig**(): `MermaidConfig` **getSiteConfig**(): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
## getSiteConfig ## getSiteConfig
@@ -78,13 +78,13 @@ The currentConfig
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
The siteConfig The siteConfig
#### Defined in #### Defined in
[config.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L96) [packages/mermaid/src/config.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L96)
--- ---
@@ -108,9 +108,9 @@ The siteConfig
#### Parameters #### Parameters
| Name | Type | Default value | Description | | Name | Type | Default value | Description |
| :------- | :-------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | | :------- | :-------------------------------------------------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `config` | `MermaidConfig` | `siteConfig` | base set of values, which currentConfig could be **reset** to. Defaults to the current siteConfig (e.g returned by [getSiteConfig](config.md#getsiteconfig)). | | `config` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) | `siteConfig` | base set of values, which currentConfig could be **reset** to. Defaults to the current siteConfig (e.g returned by [getSiteConfig](config.md#getsiteconfig)). |
#### Returns #### Returns
@@ -118,7 +118,7 @@ The siteConfig
#### Defined in #### Defined in
[config.ts:218](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L218) [packages/mermaid/src/config.ts:218](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L218)
--- ---
@@ -147,7 +147,7 @@ options in-place
#### Defined in #### Defined in
[config.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L146) [packages/mermaid/src/config.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L146)
--- ---
@@ -157,9 +157,9 @@ options in-place
#### Parameters #### Parameters
| Name | Type | | Name | Type |
| :----- | :-------------- | | :----- | :-------------------------------------------------------- |
| `conf` | `MermaidConfig` | | `conf` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) |
#### Returns #### Returns
@@ -167,13 +167,13 @@ options in-place
#### Defined in #### Defined in
[config.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L75) [packages/mermaid/src/config.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L75)
--- ---
### setConfig ### setConfig
**setConfig**(`conf`): `MermaidConfig` **setConfig**(`conf`): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
## setConfig ## setConfig
@@ -187,25 +187,25 @@ corresponding siteConfig value.
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |
| :----- | :-------------- | :-------------------------- | | :----- | :-------------------------------------------------------- | :-------------------------- |
| `conf` | `MermaidConfig` | The potential currentConfig | | `conf` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) | The potential currentConfig |
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
The currentConfig merged with the sanitized conf The currentConfig merged with the sanitized conf
#### Defined in #### Defined in
[config.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L113) [packages/mermaid/src/config.ts:113](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L113)
--- ---
### setSiteConfig ### setSiteConfig
**setSiteConfig**(`conf`): `MermaidConfig` **setSiteConfig**(`conf`): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
## setSiteConfig ## setSiteConfig
@@ -220,57 +220,57 @@ function _Default value: At default, will mirror Global Config_
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |
| :----- | :-------------- | :------------------------------------------ | | :----- | :-------------------------------------------------------- | :------------------------------------------ |
| `conf` | `MermaidConfig` | The base currentConfig to use as siteConfig | | `conf` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) | The base currentConfig to use as siteConfig |
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
The new siteConfig The new siteConfig
#### Defined in #### Defined in
[config.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L61) [packages/mermaid/src/config.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L61)
--- ---
### updateCurrentConfig ### updateCurrentConfig
**updateCurrentConfig**(`siteCfg`, `_directives`): `MermaidConfig` **updateCurrentConfig**(`siteCfg`, `_directives`): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
#### Parameters #### Parameters
| Name | Type | | Name | Type |
| :------------ | :----------------- | | :------------ | :----------------------------------------------------------- |
| `siteCfg` | `MermaidConfig` | | `siteCfg` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) |
| `_directives` | `MermaidConfig`\[] | | `_directives` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)\[] |
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
#### Defined in #### Defined in
[config.ts:15](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L15) [packages/mermaid/src/config.ts:15](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L15)
--- ---
### updateSiteConfig ### updateSiteConfig
**updateSiteConfig**(`conf`): `MermaidConfig` **updateSiteConfig**(`conf`): [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
#### Parameters #### Parameters
| Name | Type | | Name | Type |
| :----- | :-------------- | | :----- | :-------------------------------------------------------- |
| `conf` | `MermaidConfig` | | `conf` | [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md) |
#### Returns #### Returns
`MermaidConfig` [`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)
#### Defined in #### Defined in
[config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79) [packages/mermaid/src/config.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L79)

View File

@@ -14,13 +14,13 @@
#### Defined in #### Defined in
[defaultConfig.ts:275](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L275) [packages/mermaid/src/defaultConfig.ts:275](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L275)
--- ---
### default ### default
`Const` **default**: `RequiredDeep`<`MermaidConfig`> `Const` **default**: `RequiredDeep`<[`MermaidConfig`](../interfaces/mermaid.MermaidConfig.md)>
Default mermaid configuration options. Default mermaid configuration options.
@@ -30,4 +30,4 @@ Non-JSON JS default values are listed in this file, e.g. functions, or
#### Defined in #### Defined in
[defaultConfig.ts:18](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L18) [packages/mermaid/src/defaultConfig.ts:18](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L18)

View File

@@ -0,0 +1,57 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/modules/mermaid.md](../../../../packages/mermaid/src/docs/config/setup/modules/mermaid.md).
# Module: mermaid
## Classes
- [UnknownDiagramError](../classes/mermaid.UnknownDiagramError.md)
## Interfaces
- [DetailedError](../interfaces/mermaid.DetailedError.md)
- [ExternalDiagramDefinition](../interfaces/mermaid.ExternalDiagramDefinition.md)
- [Mermaid](../interfaces/mermaid.Mermaid.md)
- [MermaidConfig](../interfaces/mermaid.MermaidConfig.md)
- [ParseOptions](../interfaces/mermaid.ParseOptions.md)
- [ParseResult](../interfaces/mermaid.ParseResult.md)
- [RenderResult](../interfaces/mermaid.RenderResult.md)
- [RunOptions](../interfaces/mermaid.RunOptions.md)
## Type Aliases
### ParseErrorFunction
Ƭ **ParseErrorFunction**: (`err`: `string` | [`DetailedError`](../interfaces/mermaid.DetailedError.md) | `unknown`, `hash?`: `any`) => `void`
#### Type declaration
▸ (`err`, `hash?`): `void`
##### Parameters
| Name | Type |
| :------ | :--------------------------------------------------------------------------------- |
| `err` | `string` \| [`DetailedError`](../interfaces/mermaid.DetailedError.md) \| `unknown` |
| `hash?` | `any` |
##### Returns
`void`
#### Defined in
[packages/mermaid/src/Diagram.ts:10](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/Diagram.ts#L10)
## Variables
### default
`Const` **default**: [`Mermaid`](../interfaces/mermaid.Mermaid.md)
#### Defined in
[packages/mermaid/src/mermaid.ts:430](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaid.ts#L430)

View File

@@ -1,284 +0,0 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/modules/mermaidAPI.md](../../../../packages/mermaid/src/docs/config/setup/modules/mermaidAPI.md).
# Module: mermaidAPI
## Interfaces
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
- [ParseResult](../interfaces/mermaidAPI.ParseResult.md)
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
## References
### default
Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
## Type Aliases
### D3Element
Ƭ **D3Element**: `any`
#### Defined in
[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74)
## Variables
### mermaidAPI
`Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getDiagramFromText`: (`text`: `string`, `metadata`: `Pick`<`DiagramMetadata`, `"title"`>) => `Promise`<`Diagram`> ; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `void` ; `parse`: (`text`: `string`, `parseOptions`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md) & { `suppressErrors`: `true` }) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md) | `false`>(`text`: `string`, `parseOptions?`: [`ParseOptions`](../interfaces/mermaidAPI.ParseOptions.md)) => `Promise`<[`ParseResult`](../interfaces/mermaidAPI.ParseResult.md)> ; `render`: (`id`: `string`, `text`: `string`, `svgContainingElement?`: `Element`) => `Promise`<[`RenderResult`](../interfaces/mermaidAPI.RenderResult.md)> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
## mermaidAPI configuration defaults
```ts
const config = {
theme: 'default',
logLevel: 'fatal',
securityLevel: 'strict',
startOnLoad: true,
arrowMarkerAbsolute: false,
suppressErrorRendering: false,
er: {
diagramPadding: 20,
layoutDirection: 'TB',
minEntityWidth: 100,
minEntityHeight: 75,
entityPadding: 15,
stroke: 'gray',
fill: 'honeydew',
fontSize: 12,
useMaxWidth: true,
},
flowchart: {
diagramPadding: 8,
htmlLabels: true,
curve: 'basis',
},
sequence: {
diagramMarginX: 50,
diagramMarginY: 10,
actorMargin: 50,
width: 150,
height: 65,
boxMargin: 10,
boxTextMargin: 5,
noteMargin: 10,
messageMargin: 35,
messageAlign: 'center',
mirrorActors: true,
bottomMarginAdj: 1,
useMaxWidth: true,
rightAngles: false,
showSequenceNumbers: false,
},
gantt: {
titleTopMargin: 25,
barHeight: 20,
barGap: 4,
topPadding: 50,
leftPadding: 75,
gridLineStartPadding: 35,
fontSize: 11,
fontFamily: '"Open Sans", sans-serif',
numberSectionStyles: 4,
axisFormat: '%Y-%m-%d',
topAxis: false,
displayMode: '',
},
};
mermaid.initialize(config);
```
#### Defined in
[mermaidAPI.ts:635](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L635)
## Functions
### appendDivSvgG
**appendDivSvgG**(`parentRoot`, `id`, `enclosingDivId`, `divStyle?`, `svgXlink?`): `any`
Append an enclosing div, then svg, then g (group) to the d3 parentRoot. Set attributes.
Only set the style attribute on the enclosing div if divStyle is given.
Only set the xmlns:xlink attribute on svg if svgXlink is given.
Return the last node appended
#### Parameters
| Name | Type | Description |
| :--------------- | :------- | :----------------------------------------------- |
| `parentRoot` | `any` | the d3 node to append things to |
| `id` | `string` | the value to set the id attr to |
| `enclosingDivId` | `string` | the id to set the enclosing div to |
| `divStyle?` | `string` | if given, the style to set the enclosing div to |
| `svgXlink?` | `string` | if given, the link to set the new svg element to |
#### Returns
`any`
- returns the parentRoot that had nodes appended
#### Defined in
[mermaidAPI.ts:277](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L277)
---
### cleanUpSvgCode
**cleanUpSvgCode**(`svgCode?`, `inSandboxMode`, `useArrowMarkerUrls`): `string`
Clean up svgCode. Do replacements needed
#### Parameters
| Name | Type | Default value | Description |
| :------------------- | :-------- | :------------ | :---------------------------------------------------------- |
| `svgCode` | `string` | `''` | the code to clean up |
| `inSandboxMode` | `boolean` | `undefined` | security level |
| `useArrowMarkerUrls` | `boolean` | `undefined` | should arrow marker's use full urls? (vs. just the anchors) |
#### Returns
`string`
the cleaned up svgCode
#### Defined in
[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223)
---
### createCssStyles
**createCssStyles**(`config`, `classDefs?`): `string`
Create the user styles
#### Parameters
| Name | Type | Description |
| :---------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ |
| `config` | `MermaidConfig` | configuration that has style and theme settings to use |
| `classDefs` | `undefined` \| `null` \| `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) |
#### Returns
`string`
the string with all the user styles
#### Defined in
[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153)
---
### createUserStyles
**createUserStyles**(`config`, `graphType`, `classDefs`, `svgId`): `string`
#### Parameters
| Name | Type |
| :---------- | :-------------------------------------------------------- |
| `config` | `MermaidConfig` |
| `graphType` | `string` |
| `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> |
| `svgId` | `string` |
#### Returns
`string`
#### Defined in
[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200)
---
### cssImportantStyles
**cssImportantStyles**(`cssClass`, `element`, `cssClasses?`): `string`
Create a CSS style that starts with the given class name, then the element,
with an enclosing block that has each of the cssClasses followed by !important;
#### Parameters
| Name | Type | Default value | Description |
| :----------- | :---------- | :------------ | :--------------------------------------------- |
| `cssClass` | `string` | `undefined` | CSS class name |
| `element` | `string` | `undefined` | CSS element |
| `cssClasses` | `string`\[] | `[]` | list of CSS styles to append after the element |
#### Returns
`string`
- the constructed string
#### Defined in
[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138)
---
### putIntoIFrame
**putIntoIFrame**(`svgCode?`, `svgElement?`): `string`
Put the svgCode into an iFrame. Return the iFrame code
#### Parameters
| Name | Type | Default value | Description |
| :------------ | :------- | :------------ | :--------------------------------------------------------------------------- |
| `svgCode` | `string` | `''` | the svg code to put inside the iFrame |
| `svgElement?` | `any` | `undefined` | the d3 node that has the current svgElement so we can get the height from it |
#### Returns
`string`
- the code with the iFrame that now contains the svgCode
TODO replace btoa(). Replace with buf.toString('base64')?
#### Defined in
[mermaidAPI.ts:254](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L254)
---
### removeExistingElements
**removeExistingElements**(`doc`, `id`, `divId`, `iFrameId`): `void`
Remove any existing elements from the given document
#### Parameters
| Name | Type | Description |
| :--------- | :--------- | :------------------------------------ |
| `doc` | `Document` | the document to removed elements from |
| `id` | `string` | id for any existing SVG element |
| `divId` | `string` | - |
| `iFrameId` | `string` | - |
#### Returns
`void`
#### Defined in
[mermaidAPI.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L327)

View File

@@ -24,12 +24,12 @@ Themes can now be customized at the site-wide level, or on individual Mermaid di
## Site-wide Theme ## Site-wide Theme
To customize themes site-wide, call the `initialize` method on the `mermaidAPI`. To customize themes site-wide, call the `initialize` method on the `mermaid`.
Example of `initialize` call setting `theme` to `base`: Example of `initialize` call setting `theme` to `base`:
```javascript ```javascript
mermaidAPI.initialize({ mermaid.initialize({
securityLevel: 'loose', securityLevel: 'loose',
theme: 'base', theme: 'base',
}); });

View File

@@ -193,7 +193,7 @@ await mermaid.run({
### Calling `mermaid.init` - Deprecated ### Calling `mermaid.init` - Deprecated
> **Warning** > **Warning**
> mermaid.init is deprecated in v10 and will be removed in v11. Please use mermaid.run instead. > mermaid.init is deprecated in v10 and will be removed in a future release. Please use mermaid.run instead.
By default, `mermaid.init` will be called when the document is ready, finding all elements with By default, `mermaid.init` will be called when the document is ready, finding all elements with
`class="mermaid"`. If you are adding content after mermaid is loaded, or otherwise need `class="mermaid"`. If you are adding content after mermaid is loaded, or otherwise need
@@ -217,9 +217,6 @@ Or with no config object, and a jQuery selection:
mermaid.init(undefined, $('#someId .yetAnotherClass')); mermaid.init(undefined, $('#someId .yetAnotherClass'));
``` ```
> **Warning**
> This type of integration is deprecated. Instead the preferred way of handling more complex integration is to use the mermaidAPI instead.
## Usage with webpack ## Usage with webpack
mermaid fully supports webpack. Here is a [working demo](https://github.com/mermaidjs/mermaid-webpack-demo). mermaid fully supports webpack. Here is a [working demo](https://github.com/mermaidjs/mermaid-webpack-demo).

View File

@@ -42,6 +42,8 @@ To add an integration to this list, see the [Integrations - create page](./integ
- [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview) - [CloudScript.io Mermaid Addon](https://marketplace.atlassian.com/apps/1219878/cloudscript-io-mermaid-addon?hosting=cloud&tab=overview)
- [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅ - [Azure Devops](https://learn.microsoft.com/en-us/azure/devops/project/wiki/markdown-guidance?view=azure-devops#add-mermaid-diagrams-to-a-wiki-page) ✅
- [Deepdwn](https://billiam.itch.io/deepdwn) ✅ - [Deepdwn](https://billiam.itch.io/deepdwn) ✅
- [Doctave](https://www.doctave.com/) ✅
- [Mermaid in Markdown code blocks](https://docs.doctave.com/components/mermaid) ✅
- [GitBook](https://gitbook.com) - [GitBook](https://gitbook.com)
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid) - [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
- [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf) - [Mermaid plugin for GitBook](https://github.com/wwformat/gitbook-plugin-mermaid-pdf)
@@ -240,6 +242,8 @@ Communication tools and platforms
### Other ### Other
- [Astro](https://astro.build/)
- [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/)
- [Bisheng](https://www.npmjs.com/package/bisheng) - [Bisheng](https://www.npmjs.com/package/bisheng)
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid) - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
- [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki) - [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki)
@@ -249,6 +253,7 @@ Communication tools and platforms
- [Jekyll](https://jekyllrb.com/) - [Jekyll](https://jekyllrb.com/)
- [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid) - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
- [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams) - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
- [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/)
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic) - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server) - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅ - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅

View File

@@ -6,6 +6,10 @@
# Mermaid Chart # Mermaid Chart
The Future of Diagramming & Visual Collaboration
Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
<br /> <br />
<a href="https://www.producthunt.com/posts/mermaid-chart?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-mermaid&#0045;chart" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=416671&theme=light" alt="Mermaid&#0032;Chart - A&#0032;smarter&#0032;way&#0032;to&#0032;create&#0032;diagrams | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a> <a href="https://www.producthunt.com/posts/mermaid-chart?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-mermaid&#0045;chart" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=416671&theme=light" alt="Mermaid&#0032;Chart - A&#0032;smarter&#0032;way&#0032;to&#0032;create&#0032;diagrams | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
@@ -18,22 +22,26 @@
- **Editor** - A web based editor for creating and editing Mermaid diagrams. - **Editor** - A web based editor for creating and editing Mermaid diagrams.
- **Presentation** - A presentation mode for viewing Mermaid diagrams in a slideshow format. - **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro plan). - **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions.
- **Plugins** - A plugin system for extending the functionality of Mermaid. - **Plugins** - A plugin system for extending the functionality of Mermaid.
Plugins are available for: Official Mermaid Chart plugins:
- [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) - [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart)
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)
- [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart) - [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart)
- [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview) - [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview)
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)
- **AI diagramming** - A feature for generating Mermaid diagrams from text using AI (Pro plan). Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information.
- **More** - To learn more, visit our [Product](https://www.mermaidchart.com/product) page. - **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro and Enterprise plans).
- **Comments** - Enhance collaboration by adding comments to diagrams.
- **Presentations** - A presentation mode for viewing Mermaid diagrams in a slideshow format.
## Plans ## Plans
@@ -43,11 +51,9 @@
- **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more. - **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more.
## Access To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). Mermaid Chart is currently offering a 14-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
Mermaid Chart is currently offering a 14-day free trial of our newly-launched Pro tier. To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
## Mermaid JS contributions ## Mermaid JS contributions

View File

@@ -157,7 +157,7 @@ For a list of Mermaid Plugins and Integrations, visit the [Integrations page](..
Mermaid Chart plugins are available for: Mermaid Chart plugins are available for:
- [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) - [ChatGPT](https://docs.mermaidchart.com/plugins/mermaid-chart-gpt)
- [JetBrains IDE](https://docs.mermaidchart.com/plugins/jetbrains-ide) - [JetBrains IDE](https://docs.mermaidchart.com/plugins/jetbrains-ide)
- [Microsoft PowerPoint](https://docs.mermaidchart.com/plugins/microsoft-powerpoint) - [Microsoft PowerPoint](https://docs.mermaidchart.com/plugins/microsoft-powerpoint)
- [Microsoft Word](https://docs.mermaidchart.com/plugins/microsoft-word) - [Microsoft Word](https://docs.mermaidchart.com/plugins/microsoft-word)

View File

@@ -6,6 +6,18 @@
# Blog # Blog
## [How to Choose the Right Documentation Software](https://www.mermaidchart.com/blog/posts/how-to-choose-the-right-documentation-software/)
7 May 2024 · 5 mins
How to Choose the Right Documentation Software. Reliable and efficient documentation software is crucial in the fast-paced world of software development.
## [AI in software diagramming: What trends will define the future?](https://www.mermaidchart.com/blog/posts/ai-in-software-diagramming/)
24 April 2024 · 5 mins
Artificial intelligence (AI) tools are changing the way developers work.
## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/) ## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/)
8 April 2024 · 5 mins 8 April 2024 · 5 mins

View File

@@ -881,7 +881,7 @@ Examples of tooltip usage below:
```html ```html
<script> <script>
const callback = function () { window.callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
</script> </script>
@@ -913,7 +913,7 @@ flowchart LR
> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. > **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2.
?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/Ogglas/2o73vdez/7). ?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/yk4h7qou/2/).
Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported):
@@ -957,7 +957,7 @@ Beginner's tip—a full example using interactive links in a html context:
</pre> </pre>
<script> <script>
const callback = function () { window.callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
const config = { const config = {

View File

@@ -206,18 +206,20 @@ Messages can be of two displayed either solid or with a dotted line.
[Actor][Arrow][Actor]:Message text [Actor][Arrow][Actor]:Message text
``` ```
There are six types of arrows currently supported: There are ten types of arrows currently supported:
| Type | Description | | Type | Description |
| ------ | ------------------------------------------------ | | -------- | ------------------------------------------------------------------------ |
| `->` | Solid line without arrow | | `->` | Solid line without arrow |
| `-->` | Dotted line without arrow | | `-->` | Dotted line without arrow |
| `->>` | Solid line with arrowhead | | `->>` | Solid line with arrowhead |
| `-->>` | Dotted line with arrowhead | | `-->>` | Dotted line with arrowhead |
| `-x` | Solid line with a cross at the end | | `<<->>` | Solid line with bidirectional arrowheads (v\<MERMAID_RELEASE_VERSION>+) |
| `--x` | Dotted line with a cross at the end. | | `<<-->>` | Dotted line with bidirectional arrowheads (v\<MERMAID_RELEASE_VERSION>+) |
| `-)` | Solid line with an open arrow at the end (async) | | `-x` | Solid line with a cross at the end |
| `--)` | Dotted line with a open arrow at the end (async) | | `--x` | Dotted line with a cross at the end. |
| `-)` | Solid line with an open arrow at the end (async) |
| `--)` | Dotted line with a open arrow at the end (async) |
## Activations ## Activations
@@ -304,17 +306,35 @@ sequenceDiagram
Note over Alice,John: A typical interaction Note over Alice,John: A typical interaction
``` ```
It is also possible to add a line break (applies to text input in general): ## Line breaks
Line break can be added to Note and Message:
```mermaid-example ```mermaid-example
sequenceDiagram sequenceDiagram
Alice->John: Hello John, how are you? Alice->John: Hello John,<br/>how are you?
Note over Alice,John: A typical interaction<br/>But now in two lines Note over Alice,John: A typical interaction<br/>But now in two lines
``` ```
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
Alice->John: Hello John, how are you? Alice->John: Hello John,<br/>how are you?
Note over Alice,John: A typical interaction<br/>But now in two lines
```
Line breaks in Actor names requires aliases:
```mermaid-example
sequenceDiagram
participant Alice as Alice<br/>Johnson
Alice->John: Hello John,<br/>how are you?
Note over Alice,John: A typical interaction<br/>But now in two lines
```
```mermaid
sequenceDiagram
participant Alice as Alice<br/>Johnson
Alice->John: Hello John,<br/>how are you?
Note over Alice,John: A typical interaction<br/>But now in two lines Note over Alice,John: A typical interaction<br/>But now in two lines
``` ```

View File

@@ -483,8 +483,8 @@ a _[valid CSS property name](https://www.w3.org/TR/CSS/#properties)_ followed by
Here is an example of a classDef with just one property-value pair: Here is an example of a classDef with just one property-value pair:
``` ```txt
classDef movement font-style:italic; classDef movement font-style:italic;
``` ```
where where
@@ -496,8 +496,8 @@ If you want to have more than one _property-value pair_ then you put a comma (`,
Here is an example with three property-value pairs: Here is an example with three property-value pairs:
``` ```txt
classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow classDef badBadEvent fill:#f00,color:white,font-weight:bold,stroke-width:2px,stroke:yellow
``` ```
where where
@@ -522,7 +522,7 @@ There are two ways to apply a `classDef` style to a state:
A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is: A `class` statement tells Mermaid to apply the named classDef to one or more classes. The form is:
```txt ```txt
class [one or more state names, separated by commas] [name of a style defined with classDef] class [one or more state names, separated by commas] [name of a style defined with classDef]
``` ```
Here is an example applying the `badBadEvent` style to a state named `Crash`: Here is an example applying the `badBadEvent` style to a state named `Crash`:

221
eslint.config.js Normal file
View File

@@ -0,0 +1,221 @@
import cspell from '@cspell/eslint-plugin';
import eslint from '@eslint/js';
import cypress from 'eslint-plugin-cypress';
import jsdoc from 'eslint-plugin-jsdoc';
import json from 'eslint-plugin-json';
import lodash from 'eslint-plugin-lodash';
import markdown from 'eslint-plugin-markdown';
import noOnlyTests from 'eslint-plugin-no-only-tests';
import tsdoc from 'eslint-plugin-tsdoc';
import unicorn from 'eslint-plugin-unicorn';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
ignores: [
'**/dist/',
'**/node_modules/',
'.git/',
'**/generated/',
'**/coverage/',
'packages/mermaid/src/config.type.ts',
],
},
{
languageOptions: {
parserOptions: {
project: [
'./tsconfig.eslint.json',
'./packages/*/tsconfig.json',
'./packages/*/tsconfig.eslint.json',
'./packages/mermaid/src/docs/tsconfig.json',
],
tsconfigRootDir: import.meta.dirname,
},
globals: {
...globals.browser,
...globals.node,
...globals.es2020,
...globals.jest,
cy: 'readonly',
Cypress: 'readonly',
},
},
},
{
plugins: {
json,
'@cspell': cspell,
'no-only-tests': noOnlyTests,
lodash,
unicorn,
cypress,
markdown,
tsdoc,
jsdoc,
},
rules: {
curly: 'error',
'no-console': 'error',
'no-prototype-builtins': 'off',
'no-unused-vars': 'off',
'cypress/no-async-tests': 'off',
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'after-used',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-expect-error': 'allow-with-description',
'ts-ignore': 'allow-with-description',
'ts-nocheck': 'allow-with-description',
'ts-check': 'allow-with-description',
minimumDescriptionLength: 10,
},
],
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'typeLike',
format: ['PascalCase'],
custom: {
regex: '^I[A-Z]',
match: false,
},
},
],
// 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',
{
checkIdentifiers: true,
checkStrings: true,
checkStringTemplates: true,
},
],
'no-empty': [
'error',
{
allowEmptyCatch: true,
},
],
'no-only-tests/no-only-tests': 'error',
'lodash/import-scope': ['error', 'method'],
'unicorn/better-regex': 'error',
'unicorn/no-abusive-eslint-disable': 'error',
'unicorn/no-array-push-push': 'error',
'unicorn/no-for-loop': 'error',
'unicorn/no-instanceof-array': 'error',
'unicorn/no-typeof-undefined': 'error',
'unicorn/no-unnecessary-await': 'error',
'unicorn/no-unsafe-regex': 'warn',
'unicorn/no-useless-promise-resolve-reject': 'error',
'unicorn/prefer-array-find': 'error',
'unicorn/prefer-array-flat-map': 'error',
'unicorn/prefer-array-index-of': 'error',
'unicorn/prefer-array-some': 'error',
'unicorn/prefer-default-parameters': 'error',
'unicorn/prefer-includes': 'error',
'unicorn/prefer-negative-index': 'error',
'unicorn/prefer-object-from-entries': 'error',
'unicorn/prefer-string-starts-ends-with': 'error',
'unicorn/prefer-string-trim-start-end': 'error',
'unicorn/string-content': 'error',
'unicorn/prefer-spread': 'error',
'unicorn/no-lonely-if': 'error',
},
},
{
files: ['cypress/**', 'demos/**'],
rules: {
'no-console': 'off',
},
},
{
files: ['**/*.{js,jsx,mjs,cjs}'],
rules: {
'jsdoc/check-indentation': 'off',
'jsdoc/check-alignment': 'off',
'jsdoc/check-line-alignment': 'off',
'jsdoc/multiline-blocks': 'off',
'jsdoc/newline-after-description': 'off',
'jsdoc/tag-lines': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-param-type': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-returns-description': 'off',
},
},
{
files: ['**/*.{ts,tsx}'],
rules: {
'no-restricted-syntax': [
'error',
{
selector: 'TSEnumDeclaration',
message:
'Prefer using TypeScript union types over TypeScript enum, since TypeScript enums have a bunch of issues, see https://dev.to/dvddpl/whats-the-problem-with-typescript-enums-2okj',
},
],
'tsdoc/syntax': 'error',
},
},
{
files: ['**/*.spec.{ts,js}', 'cypress/**', 'demos/**', '**/docs/**'],
rules: {
'jsdoc/require-jsdoc': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
{
files: ['**/*.spec.{ts,js}', 'tests/**', 'cypress/**/*.js'],
rules: {
'@cspell/spellchecker': [
'error',
{
checkIdentifiers: false,
checkStrings: false,
checkStringTemplates: false,
},
],
},
},
{
files: ['*.html', '*.md', '**/*.md/*'],
rules: {
'no-var': 'error',
'no-undef': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': 'off',
},
processor: 'markdown/markdown',
}
);

View File

@@ -4,7 +4,7 @@
"version": "10.2.4", "version": "10.2.4",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module", "type": "module",
"packageManager": "pnpm@8.15.7", "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a",
"keywords": [ "keywords": [
"diagram", "diagram",
"markdown", "markdown",
@@ -19,14 +19,14 @@
"build:esbuild": "pnpm run -r clean && tsx .esbuild/build.ts", "build:esbuild": "pnpm run -r clean && tsx .esbuild/build.ts",
"build:mermaid": "pnpm build:esbuild --mermaid", "build:mermaid": "pnpm build:esbuild --mermaid",
"build:viz": "pnpm build:esbuild --visualize", "build:viz": "pnpm build:esbuild --visualize",
"build:types": "tsx .build/types.ts", "build:types": "pnpm --filter mermaid types:build-config && tsx .build/types.ts",
"build:types:watch": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly --watch", "build:types:watch": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly --watch",
"dev": "tsx .esbuild/server.ts", "dev": "tsx .esbuild/server.ts",
"dev:vite": "tsx .vite/server.ts", "dev:vite": "tsx .vite/server.ts",
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite", "dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
"release": "pnpm build", "release": "pnpm build",
"lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .", "lint": "eslint --quiet --stats --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .",
"lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts", "lint:fix": "eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts",
"lint:jison": "tsx ./scripts/jison/lint.mts", "lint:jison": "tsx ./scripts/jison/lint.mts",
"contributors": "tsx scripts/updateContributors.ts", "contributors": "tsx scripts/updateContributors.ts",
"cypress": "cypress run", "cypress": "cypress run",
@@ -62,11 +62,12 @@
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.42.3", "@applitools/eyes-cypress": "^3.42.3",
"@cspell/eslint-plugin": "^8.6.0", "@argos-ci/cypress": "^2.1.0",
"@cspell/eslint-plugin": "^8.8.4",
"@cypress/code-coverage": "^3.12.30", "@cypress/code-coverage": "^3.12.30",
"@eslint/js": "^9.4.0",
"@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-typescript": "^11.1.6",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/eslint": "^8.56.6",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/jsdom": "^21.1.6", "@types/jsdom": "^21.1.6",
@@ -74,8 +75,6 @@
"@types/mdast": "^4.0.3", "@types/mdast": "^4.0.3",
"@types/node": "^20.11.30", "@types/node": "^20.11.30",
"@types/rollup-plugin-visualizer": "^4.2.4", "@types/rollup-plugin-visualizer": "^4.2.4",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"@vitest/coverage-v8": "^1.4.0", "@vitest/coverage-v8": "^1.4.0",
"@vitest/spy": "^1.4.0", "@vitest/spy": "^1.4.0",
"@vitest/ui": "^1.4.0", "@vitest/ui": "^1.4.0",
@@ -87,27 +86,28 @@
"cspell": "^8.6.0", "cspell": "^8.6.0",
"cypress": "^13.7.1", "cypress": "^13.7.1",
"cypress-image-snapshot": "^4.0.1", "cypress-image-snapshot": "^4.0.1",
"esbuild": "^0.20.2", "esbuild": "^0.21.5",
"eslint": "^8.57.0", "eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-cypress": "^2.15.1", "eslint-plugin-cypress": "^3.3.0",
"eslint-plugin-html": "^8.0.0", "eslint-plugin-html": "^8.1.1",
"eslint-plugin-jest": "^27.9.0", "eslint-plugin-jest": "^28.6.0",
"eslint-plugin-jsdoc": "^48.2.1", "eslint-plugin-jsdoc": "^48.2.9",
"eslint-plugin-json": "^3.1.0", "eslint-plugin-json": "^4.0.0",
"eslint-plugin-lodash": "^7.4.0", "eslint-plugin-lodash": "^8.0.0",
"eslint-plugin-markdown": "^4.0.1", "eslint-plugin-markdown": "^5.0.0",
"eslint-plugin-no-only-tests": "^3.1.0", "eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-tsdoc": "^0.3.0",
"eslint-plugin-unicorn": "^51.0.1", "eslint-plugin-unicorn": "^54.0.0",
"express": "^4.19.1", "express": "^4.19.1",
"globals": "^15.4.0",
"globby": "^14.0.1", "globby": "^14.0.1",
"husky": "^9.0.11", "husky": "^9.0.11",
"jest": "^29.7.0", "jest": "^29.7.0",
"jison": "^0.4.18", "jison": "^0.4.18",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"langium-cli": "3.0.1", "langium-cli": "3.0.3",
"lint-staged": "^15.2.2", "lint-staged": "^15.2.2",
"markdown-table": "^3.0.3", "markdown-table": "^3.0.3",
"nyc": "^15.1.0", "nyc": "^15.1.0",
@@ -119,17 +119,13 @@
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"start-server-and-test": "^2.0.3", "start-server-and-test": "^2.0.3",
"tsx": "^4.7.1", "tsx": "^4.7.1",
"typescript": "^5.4.3", "typescript": "~5.4.5",
"typescript-eslint": "^8.0.0-alpha.34",
"vite": "^5.2.3", "vite": "^5.2.3",
"vite-plugin-istanbul": "^6.0.0", "vite-plugin-istanbul": "^6.0.0",
"vitest": "^1.4.0" "vitest": "^1.4.0"
}, },
"nyc": { "nyc": {
"report-dir": "coverage/cypress" "report-dir": "coverage/cypress"
},
"pnpm": {
"patchedDependencies": {
"cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch"
}
} }
} }

View File

@@ -25,7 +25,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
fatal: warning, 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 getConfig: () => object;
export let sanitizeText: (str: string) => string; export let sanitizeText: (str: string) => string;
export let commonDb: () => object; export let commonDb: () => object;

View File

@@ -0,0 +1,11 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": ["./tsconfig.json"],
"compilerOptions": {
"noEmit": true
},
"include": [
"./src/**/*.spec.js",
"./src/**/*.spec.ts" // test files
]
}

View File

@@ -39,6 +39,26 @@ describe('flowchart-elk detector', () => {
).toBe(true); ).toBe(true);
}); });
// The error from the issue was reproduced with mindmap, so this is just an example
// what matters is the keyword somewhere inside graph definition
it('should check only the beginning of the line in search of keywords', () => {
expect(
detector('mindmap ["Descendant node in flowchart"]', {
flowchart: {
defaultRenderer: 'elk',
},
})
).toBe(false);
expect(
detector('mindmap ["Descendant node in graph"]', {
flowchart: {
defaultRenderer: 'elk',
},
})
).toBe(false);
});
it('should detect flowchart-elk', () => { it('should detect flowchart-elk', () => {
expect(detector('flowchart-elk')).toBe(true); expect(detector('flowchart-elk')).toBe(true);
}); });

View File

@@ -11,7 +11,7 @@ const detector: DiagramDetector = (txt, config): boolean => {
// If diagram explicitly states flowchart-elk // If diagram explicitly states flowchart-elk
/^\s*flowchart-elk/.test(txt) || /^\s*flowchart-elk/.test(txt) ||
// If a flowchart/graph diagram has their default renderer set to elk // If a flowchart/graph diagram has their default renderer set to elk
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk') (/^\s*(flowchart|graph)/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
) { ) {
return true; return true;
} }

View File

@@ -41,12 +41,12 @@ let nodeDb = {};
export const addVertices = async function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) { export const addVertices = async function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) {
const svg = root.select(`[id="${svgId}"]`); const svg = root.select(`[id="${svgId}"]`);
const nodes = svg.insert('g').attr('class', 'nodes'); const nodes = svg.insert('g').attr('class', 'nodes');
const keys = Object.keys(vert); const keys = [...vert.keys()];
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
await Promise.all( await Promise.all(
keys.map(async function (id) { keys.map(async function (id) {
const vertex = vert[id]; const vertex = vert.get(id);
/** /**
* Variable for storing the classes for the vertex * Variable for storing the classes for the vertex
@@ -64,7 +64,6 @@ export const addVertices = async function (vert, svgId, root, doc, diagObj, pare
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id; let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
// We create a SVG label, either by delegating to addHtmlLabel or manually // We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
const labelData = { width: 0, height: 0 }; const labelData = { width: 0, height: 0 };
const ports = [ const ports = [
@@ -188,19 +187,6 @@ export const addVertices = async function (vert, svgId, root, doc, diagObj, pare
nodeEl = await insertNode(nodes, node, vertex.dir); nodeEl = await insertNode(nodes, node, vertex.dir);
boundingBox = nodeEl.node().getBBox(); boundingBox = nodeEl.node().getBBox();
} else { } else {
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
// svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
// const rows = vertexText.split(common.lineBreakRegex);
// for (const row of rows) {
// const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
// tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
// tspan.setAttribute('dy', '1em');
// tspan.setAttribute('x', '1');
// tspan.textContent = row;
// svgLabel.appendChild(tspan);
// }
// vertexNode = svgLabel;
// const bbox = vertexNode.getBBox();
const { shapeSvg, bbox } = await labelHelper(nodes, node, undefined, true); const { shapeSvg, bbox } = await labelHelper(nodes, node, undefined, true);
labelData.width = bbox.width; labelData.width = bbox.width;
labelData.wrappingWidth = getConfig().flowchart.wrappingWidth; labelData.wrappingWidth = getConfig().flowchart.wrappingWidth;
@@ -595,7 +581,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
* *
* @param text * @param text
* @param diagObj * @param diagObj
* @returns {Record<string, import('../../mermaid/src/diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles * @returns {Map<string, import('../../mermaid/src/diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
*/ */
export const getClasses = function (text, diagObj) { export const getClasses = function (text, diagObj) {
log.info('Extracting classes'); log.info('Extracting classes');

View File

@@ -34,7 +34,7 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@zenuml/core": "^3.19.2" "@zenuml/core": "^3.23.27"
}, },
"devDependencies": { "devDependencies": {
"mermaid": "workspace:^" "mermaid": "workspace:^"

View File

@@ -26,7 +26,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
fatal: warning, 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 getConfig: () => MermaidConfig;
export let sanitizeText: (str: string) => string; export let sanitizeText: (str: string) => string;
// eslint-disable @typescript-eslint/no-explicit-any // eslint-disable @typescript-eslint/no-explicit-any

View File

@@ -9,7 +9,7 @@ function createTemporaryZenumlContainer(id: string) {
container.id = `container-${id}`; container.id = `container-${id}`;
container.style.display = 'flex'; container.style.display = 'flex';
container.innerHTML = `<div id="zenUMLApp-${id}"></div>`; container.innerHTML = `<div id="zenUMLApp-${id}"></div>`;
const app = container.querySelector(`#zenUMLApp-${id}`) as HTMLElement; const app = container.querySelector(`#zenUMLApp-${id}`)!;
return { container, app }; return { container, app };
} }

View File

@@ -34,7 +34,7 @@
"scripts": { "scripts": {
"clean": "rimraf dist", "clean": "rimraf dist",
"dev": "pnpm -w dev", "dev": "pnpm -w dev",
"docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaidAPI.ts && prettier --write ./src/docs/config/setup", "docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaid.ts && prettier --write ./src/docs/config/setup",
"docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts", "docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts",
"docs:verify": "pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts --verify", "docs:verify": "pnpm docs:spellcheck && pnpm docs:code && tsx scripts/docs.cli.mts --verify",
"docs:pre:vitepress": "pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts", "docs:pre:vitepress": "pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && tsx scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts",
@@ -70,7 +70,7 @@
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^7.0.1", "@braintree/sanitize-url": "^7.0.1",
"@mermaid-js/parser": "workspace:^", "@mermaid-js/parser": "workspace:^",
"cytoscape": "^3.28.1", "cytoscape": "^3.29.2",
"cytoscape-cose-bilkent": "^4.1.0", "cytoscape-cose-bilkent": "^4.1.0",
"d3": "^7.9.0", "d3": "^7.9.0",
"d3-sankey": "^0.12.3", "d3-sankey": "^0.12.3",
@@ -81,14 +81,14 @@
"katex": "^0.16.9", "katex": "^0.16.9",
"khroma": "^2.1.0", "khroma": "^2.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mdast-util-from-markdown": "^2.0.0", "marked": "^13.0.2",
"stylis": "^4.3.1", "stylis": "^4.3.1",
"ts-dedent": "^2.2.0", "ts-dedent": "^2.2.0",
"uuid": "^9.0.1" "uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"@adobe/jsonschema2md": "^8.0.0", "@adobe/jsonschema2md": "^8.0.0",
"@types/cytoscape": "^3.19.16", "@types/cytoscape": "^3.21.4",
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"@types/d3-sankey": "^0.12.4", "@types/d3-sankey": "^0.12.4",
"@types/d3-scale": "^4.0.8", "@types/d3-scale": "^4.0.8",
@@ -103,8 +103,6 @@
"@types/prettier": "^3.0.0", "@types/prettier": "^3.0.0",
"@types/stylis": "^4.2.5", "@types/stylis": "^4.2.5",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"ajv": "^8.12.0", "ajv": "^8.12.0",
"chokidar": "^3.6.0", "chokidar": "^3.6.0",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
@@ -126,7 +124,7 @@
"type-fest": "^4.13.1", "type-fest": "^4.13.1",
"typedoc": "^0.25.12", "typedoc": "^0.25.12",
"typedoc-plugin-markdown": "^3.17.1", "typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.4.3", "typescript": "~5.4.3",
"unist-util-flatmap": "^1.0.0", "unist-util-flatmap": "^1.0.0",
"unist-util-visit": "^5.0.0", "unist-util-visit": "^5.0.0",
"vitepress": "^1.0.1", "vitepress": "^1.0.1",

View File

@@ -10,18 +10,16 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { readFile, writeFile } from 'node:fs/promises'; import _Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
import { join } from 'node:path'; import { JSON_SCHEMA, load } from 'js-yaml';
import { compile, type JSONSchema } from 'json-schema-to-typescript';
import assert from 'node:assert'; import assert from 'node:assert';
import { execFile } from 'node:child_process'; import { execFile } from 'node:child_process';
import { readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { promisify } from 'node:util'; import { promisify } from 'node:util';
import { load, JSON_SCHEMA } from 'js-yaml';
import { compile, type JSONSchema } from 'json-schema-to-typescript';
import prettier from 'prettier'; import prettier from 'prettier';
import _Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
// Workaround for wrong AJV types, see // Workaround for wrong AJV types, see
// https://github.com/ajv-validator/ajv/issues/2132#issuecomment-1290409907 // https://github.com/ajv-validator/ajv/issues/2132#issuecomment-1290409907
const Ajv2019 = _Ajv2019 as unknown as typeof _Ajv2019.default; const Ajv2019 = _Ajv2019 as unknown as typeof _Ajv2019.default;
@@ -34,28 +32,6 @@ const verifyOnly = process.argv.includes('--verify');
/** If `true`, automatically `git add` any changes (i.e. during `pnpm run pre-commit`)*/ /** If `true`, automatically `git add` any changes (i.e. during `pnpm run pre-commit`)*/
const git = process.argv.includes('--git'); const git = process.argv.includes('--git');
/**
* All of the keys in the mermaid config that have a mermaid diagram config.
*/
const MERMAID_CONFIG_DIAGRAM_KEYS = [
'flowchart',
'sequence',
'gantt',
'journey',
'class',
'state',
'er',
'pie',
'quadrantChart',
'xyChart',
'requirement',
'mindmap',
'timeline',
'gitGraph',
'c4',
'sankey',
];
/** /**
* Loads the MermaidConfig JSON schema YAML file. * Loads the MermaidConfig JSON schema YAML file.
* *
@@ -121,7 +97,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
* @returns The schema with `allOf` replaced with `extends`. * @returns The schema with `allOf` replaced with `extends`.
*/ */
function replaceAllOfWithExtends(schema: JSONSchemaType<Record<string, any>>) { function replaceAllOfWithExtends(schema: JSONSchemaType<Record<string, any>>) {
if (schema['allOf']) { if (schema.allOf) {
const { allOf, ...schemaWithoutAllOf } = schema; const { allOf, ...schemaWithoutAllOf } = schema;
return { return {
...schemaWithoutAllOf, ...schemaWithoutAllOf,
@@ -148,53 +124,9 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
return { ...schema, required: [] }; return { ...schema, required: [] };
} }
/**
* This is a temporary hack to control the order the types are generated in.
*
* By default, json-schema-to-typescript outputs the $defs in the order they
* are used, then any unused schemas at the end.
*
* **The only purpose of this function is to make the `git diff` simpler**
* **We should remove this later to simplify the code**
*
* @todo TODO: Remove this function in a future PR.
* @param schema - The input schema.
* @returns The schema with all `$ref`s removed.
*/
function unrefSubschemas(schema: JSONSchemaType<Record<string, any>>) {
return {
...schema,
properties: Object.fromEntries(
Object.entries(schema.properties).map(([key, propertySchema]) => {
if (MERMAID_CONFIG_DIAGRAM_KEYS.includes(key)) {
const { $ref, ...propertySchemaWithoutRef } = propertySchema as JSONSchemaType<unknown>;
if ($ref === undefined) {
throw Error(
`subSchema ${key} is in MERMAID_CONFIG_DIAGRAM_KEYS but does not have a $ref field`
);
}
const [
_root, // eslint-disable-line @typescript-eslint/no-unused-vars
_defs, // eslint-disable-line @typescript-eslint/no-unused-vars
defName,
] = $ref.split('/');
return [
key,
{
...propertySchemaWithoutRef,
tsType: defName,
},
];
}
return [key, propertySchema];
})
),
};
}
assert.ok(mermaidConfigSchema.$defs); assert.ok(mermaidConfigSchema.$defs);
const modifiedSchema = { const modifiedSchema = {
...unrefSubschemas(removeRequired(mermaidConfigSchema)), ...removeRequired(mermaidConfigSchema),
$defs: Object.fromEntries( $defs: Object.fromEntries(
Object.entries(mermaidConfigSchema.$defs).map(([key, subSchema]) => { Object.entries(mermaidConfigSchema.$defs).map(([key, subSchema]) => {

View File

@@ -88,9 +88,9 @@ const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DO
const prettierConfig = (await prettier.resolveConfig('.')) ?? {}; const prettierConfig = (await prettier.resolveConfig('.')) ?? {};
// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21 // From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g; const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g;
const includedFiles: Set<string> = new Set(); const includedFiles = new Set<string>();
const filesTransformed: Set<string> = new Set(); const filesTransformed = new Set<string>();
const generateHeader = (file: string): string => { const generateHeader = (file: string): string => {
// path from file in docs/* to repo root, e.g ../ or ../../ */ // path from file in docs/* to repo root, e.g ../ or ../../ */
@@ -181,10 +181,10 @@ export const transformToBlockQuote = (
) => { ) => {
if (vitepress) { if (vitepress) {
const vitepressType = type === 'note' ? 'info' : type; const vitepressType = type === 'note' ? 'info' : type;
return `::: ${vitepressType} ${customTitle || ''}\n${content}\n:::`; return `::: ${vitepressType} ${customTitle ?? ''}\n${content}\n:::`;
} else { } else {
const icon = blockIcons[type] || ''; const icon = blockIcons[type] ?? '';
const title = `${icon}${customTitle || capitalize(type)}`; const title = `${icon}${customTitle ?? capitalize(type)}`;
return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`; return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`;
} }
}; };
@@ -201,6 +201,7 @@ const transformIncludeStatements = (file: string, text: string): string => {
includedFiles.add(changeToFinalDocDir(includePath)); includedFiles.add(changeToFinalDocDir(includePath));
return content; return content;
} catch (error) { } catch (error) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`); throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`);
} }
}); });
@@ -241,7 +242,7 @@ export function transformMarkdownAst({
addEditLink, addEditLink,
removeYAML, removeYAML,
}: TransformMarkdownAstOptions) { }: TransformMarkdownAstOptions) {
return (tree: Root, _file?: any): Root => { return (tree: Root): Root => {
const astWithTransformedBlocks = flatmap(tree, (node: Code) => { const astWithTransformedBlocks = flatmap(tree, (node: Code) => {
if (node.type !== 'code' || !node.lang) { if (node.type !== 'code' || !node.lang) {
return [node]; // no transformation if this is not a code block return [node]; // no transformation if this is not a code block
@@ -509,6 +510,7 @@ export const getGlobs = (globs: string[]): string[] => {
globs.push( globs.push(
'!**/.vitepress/**', '!**/.vitepress/**',
'!**/vite.config.ts', '!**/vite.config.ts',
'!**/tsconfig.json',
'!src/docs/index.md', '!src/docs/index.md',
'!**/package.json', '!**/package.json',
'!**/user-avatars/**' '!**/user-avatars/**'

View File

@@ -6,6 +6,7 @@ import { encodeEntities } from './utils.js';
import type { DetailedError } from './utils.js'; import type { DetailedError } from './utils.js';
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.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; export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
/** /**
@@ -19,7 +20,7 @@ export class Diagram {
text = encodeEntities(text) + '\n'; text = encodeEntities(text) + '\n';
try { try {
getDiagram(type); getDiagram(type);
} catch (e) { } catch {
const loader = getDiagramLoader(type); const loader = getDiagramLoader(type);
if (!loader) { if (!loader) {
throw new UnknownDiagramError(`Diagram ${type} not found.`); throw new UnknownDiagramError(`Diagram ${type} not found.`);

View File

@@ -1,6 +1,6 @@
import { MockedD3 } from './tests/MockedD3.js'; import { MockedD3 } from './tests/MockedD3.js';
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js'; import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
import type { D3Element } from './mermaidAPI.js'; import type { D3Element } from './types.js';
describe('accessibility', () => { describe('accessibility', () => {
const fauxSvgNode: MockedD3 = new MockedD3(); const fauxSvgNode: MockedD3 = new MockedD3();

View File

@@ -5,7 +5,7 @@
* @see https://www.w3.org/TR/wai-aria-1.1/ * @see https://www.w3.org/TR/wai-aria-1.1/
* @see https://www.w3.org/TR/svg-aam-1.0/ * @see https://www.w3.org/TR/svg-aam-1.0/
*/ */
import type { D3Element } from './mermaidAPI.js'; import type { D3Element } from './types.js';
/** /**
* SVG element role: * SVG element role:

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as configApi from './config.js'; import * as configApi from './config.js';
import type { MermaidConfig } from './config.type.js'; import type { MermaidConfig } from './config.type.js';

View File

@@ -189,7 +189,7 @@ export const addDirective = (directive: MermaidConfig) => {
sanitizeDirective(directive); sanitizeDirective(directive);
// If the directive has a fontFamily, but no themeVariables, add the fontFamily to the themeVariables // 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 }; directive.themeVariables = { fontFamily: directive.fontFamily };
} }

File diff suppressed because it is too large Load Diff

View File

@@ -42,9 +42,6 @@ export const getArrowPoints = (
// Padding to use, half of the node padding. // Padding to use, half of the node padding.
const padding = node.padding / 2; const padding = node.padding / 2;
// Initialize an empty array to store points for the arrow.
const points = [];
if ( if (
directions.has('right') && directions.has('right') &&
directions.has('left') && directions.has('left') &&

View File

@@ -25,15 +25,10 @@ function addHtmlLabel(node) {
const label = node.label; const label = node.label;
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel'; const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
div.html( const span = div.append('span');
'<span class="' + span.html(label);
labelClass + applyStyle(span, node.labelStyle);
'" ' + span.attr('class', labelClass);
(node.labelStyle ? 'style="' + node.labelStyle + '"' : '') +
'>' +
label +
'</span>'
);
applyStyle(div, node.labelStyle); applyStyle(div, node.labelStyle);
div.style('display', 'inline-block'); div.style('display', 'inline-block');

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/unbound-method */
import type { Mocked } from 'vitest'; import type { Mocked } from 'vitest';
import type { SVG } from '../diagram-api/types.js'; import type { SVG } from '../diagram-api/types.js';
import { addEdgeMarkers } from './edgeMarker.js'; import { addEdgeMarkers } from './edgeMarker.js';

View File

@@ -51,7 +51,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
} }
} }
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v))); log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
if (node && node.clusterNode) { if (node?.clusterNode) {
// const children = graph.children(v); // const children = graph.children(v);
log.info('Cluster identified', v, node.width, graph.node(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 // `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: ', ' height: ',
node.height node.height
); );
if (node && node.clusterNode) { if (node?.clusterNode) {
// clusterDb[node.id].node = node; // clusterDb[node.id].node = node;
node.y += subGraphTitleTotalMargin; node.y += subGraphTitleTotalMargin;
positionNode(node); positionNode(node);

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