mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Merge branch 'develop' into patch-1
This commit is contained in:
commit
36b6733c4f
30
.build/common.ts
Normal file
30
.build/common.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Shared common options for both ESBuild and Vite
|
||||||
|
*/
|
||||||
|
export const packageOptions = {
|
||||||
|
parser: {
|
||||||
|
name: 'mermaid-parser',
|
||||||
|
packageName: 'parser',
|
||||||
|
file: 'index.ts',
|
||||||
|
},
|
||||||
|
mermaid: {
|
||||||
|
name: 'mermaid',
|
||||||
|
packageName: 'mermaid',
|
||||||
|
file: 'mermaid.ts',
|
||||||
|
},
|
||||||
|
'mermaid-example-diagram': {
|
||||||
|
name: 'mermaid-example-diagram',
|
||||||
|
packageName: 'mermaid-example-diagram',
|
||||||
|
file: 'detector.ts',
|
||||||
|
},
|
||||||
|
'mermaid-zenuml': {
|
||||||
|
name: 'mermaid-zenuml',
|
||||||
|
packageName: 'mermaid-zenuml',
|
||||||
|
file: 'detector.ts',
|
||||||
|
},
|
||||||
|
'mermaid-flowchart-elk': {
|
||||||
|
name: 'mermaid-flowchart-elk',
|
||||||
|
packageName: 'mermaid-flowchart-elk',
|
||||||
|
file: 'detector.ts',
|
||||||
|
},
|
||||||
|
} as const;
|
5
.build/generateLangium.ts
Normal file
5
.build/generateLangium.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { generate } from 'langium-cli';
|
||||||
|
|
||||||
|
export async function generateLangium() {
|
||||||
|
await generate({ file: `./packages/parser/langium-config.json` });
|
||||||
|
}
|
124
.build/jsonSchema.ts
Normal file
124
.build/jsonSchema.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import { load, JSON_SCHEMA } from 'js-yaml';
|
||||||
|
import assert from 'node:assert';
|
||||||
|
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
|
||||||
|
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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',
|
||||||
|
'block',
|
||||||
|
'packet',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate default values from the JSON Schema.
|
||||||
|
*
|
||||||
|
* AJV does not support nested default values yet (or default values with $ref),
|
||||||
|
* so we need to manually find them (this may be fixed in ajv v9).
|
||||||
|
*
|
||||||
|
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
|
||||||
|
* @returns The default mermaid config object.
|
||||||
|
*/
|
||||||
|
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
|
||||||
|
const ajv = new Ajv2019({
|
||||||
|
useDefaults: true,
|
||||||
|
allowUnionTypes: true,
|
||||||
|
strict: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
ajv.addKeyword({
|
||||||
|
keyword: 'meta:enum', // used by jsonschema2md
|
||||||
|
errors: false,
|
||||||
|
});
|
||||||
|
ajv.addKeyword({
|
||||||
|
keyword: 'tsType', // used by json-schema-to-typescript
|
||||||
|
errors: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
|
||||||
|
// (may be fixed in v9) so we need to manually use sub-schemas
|
||||||
|
const mermaidDefaultConfig = {};
|
||||||
|
|
||||||
|
assert.ok(mermaidConfigSchema.$defs);
|
||||||
|
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
|
||||||
|
|
||||||
|
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
|
||||||
|
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
|
||||||
|
const [root, defs, defName] = subSchemaRef.split('/');
|
||||||
|
assert.strictEqual(root, '#');
|
||||||
|
assert.strictEqual(defs, '$defs');
|
||||||
|
const subSchema = {
|
||||||
|
$schema: mermaidConfigSchema.$schema,
|
||||||
|
$defs: mermaidConfigSchema.$defs,
|
||||||
|
...mermaidConfigSchema.$defs[defName],
|
||||||
|
} as JSONSchemaType<BaseDiagramConfig>;
|
||||||
|
|
||||||
|
const validate = ajv.compile(subSchema);
|
||||||
|
|
||||||
|
mermaidDefaultConfig[key] = {};
|
||||||
|
|
||||||
|
for (const required of subSchema.required ?? []) {
|
||||||
|
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
|
||||||
|
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!validate(mermaidDefaultConfig[key])) {
|
||||||
|
throw new Error(
|
||||||
|
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
|
||||||
|
validate.errors,
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const validate = ajv.compile(mermaidConfigSchema);
|
||||||
|
|
||||||
|
if (!validate(mermaidDefaultConfig)) {
|
||||||
|
throw new Error(
|
||||||
|
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
|
||||||
|
validate.errors,
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mermaidDefaultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadSchema = (src: string, filename: string): JSONSchemaType<MermaidConfig> => {
|
||||||
|
const jsonSchema = load(src, {
|
||||||
|
filename,
|
||||||
|
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
||||||
|
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
||||||
|
schema: JSON_SCHEMA,
|
||||||
|
}) as JSONSchemaType<MermaidConfig>;
|
||||||
|
return jsonSchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDefaults = (schema: JSONSchemaType<MermaidConfig>) => {
|
||||||
|
return `export default ${JSON.stringify(generateDefaults(schema), undefined, 2)};`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSchema = (schema: JSONSchemaType<MermaidConfig>) => {
|
||||||
|
return `export default ${JSON.stringify(schema, undefined, 2)};`;
|
||||||
|
};
|
18
.build/types.ts
Normal file
18
.build/types.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { packageOptions } from './common.js';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
|
||||||
|
const buildType = (packageName: string) => {
|
||||||
|
console.log(`Building types for ${packageName}`);
|
||||||
|
try {
|
||||||
|
const out = execSync(`tsc -p ./packages/${packageName}/tsconfig.json --emitDeclarationOnly`);
|
||||||
|
out.length > 0 && console.log(out.toString());
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
e.stdout.length > 0 && console.error(e.stdout.toString());
|
||||||
|
e.stderr.length > 0 && console.error(e.stderr.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const { packageName } of Object.values(packageOptions)) {
|
||||||
|
buildType(packageName);
|
||||||
|
}
|
@ -53,6 +53,7 @@ GENERICTYPE
|
|||||||
getBoundarys
|
getBoundarys
|
||||||
grammr
|
grammr
|
||||||
graphtype
|
graphtype
|
||||||
|
iife
|
||||||
interp
|
interp
|
||||||
introdcued
|
introdcued
|
||||||
INVTRAPEND
|
INVTRAPEND
|
||||||
@ -74,11 +75,13 @@ loglevel
|
|||||||
LOGMSG
|
LOGMSG
|
||||||
lookaheads
|
lookaheads
|
||||||
mdast
|
mdast
|
||||||
|
metafile
|
||||||
minlen
|
minlen
|
||||||
Mstartx
|
Mstartx
|
||||||
MULT
|
MULT
|
||||||
NODIR
|
NODIR
|
||||||
NSTR
|
NSTR
|
||||||
|
outdir
|
||||||
Qcontrolx
|
Qcontrolx
|
||||||
reinit
|
reinit
|
||||||
rels
|
rels
|
||||||
|
@ -36,6 +36,7 @@ jsfiddle
|
|||||||
jsonschema
|
jsonschema
|
||||||
katex
|
katex
|
||||||
khroma
|
khroma
|
||||||
|
langium
|
||||||
mathml
|
mathml
|
||||||
matplotlib
|
matplotlib
|
||||||
mdbook
|
mdbook
|
||||||
|
65
.esbuild/build.ts
Normal file
65
.esbuild/build.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { build } from 'esbuild';
|
||||||
|
import { mkdir, writeFile } from 'node:fs/promises';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
import { generateLangium } from '../.build/generateLangium.js';
|
||||||
|
import { MermaidBuildOptions, defaultOptions, getBuildConfig } from './util.js';
|
||||||
|
|
||||||
|
const shouldVisualize = process.argv.includes('--visualize');
|
||||||
|
|
||||||
|
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||||
|
const commonOptions = { ...defaultOptions, entryName } as const;
|
||||||
|
const buildConfigs = [
|
||||||
|
// package.mjs
|
||||||
|
{ ...commonOptions },
|
||||||
|
// package.min.mjs
|
||||||
|
{
|
||||||
|
...commonOptions,
|
||||||
|
minify: true,
|
||||||
|
metafile: shouldVisualize,
|
||||||
|
},
|
||||||
|
// package.core.mjs
|
||||||
|
{ ...commonOptions, core: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (entryName === 'mermaid') {
|
||||||
|
const iifeOptions: MermaidBuildOptions = { ...commonOptions, format: 'iife' };
|
||||||
|
buildConfigs.push(
|
||||||
|
// mermaid.js
|
||||||
|
{ ...iifeOptions },
|
||||||
|
// mermaid.min.js
|
||||||
|
{ ...iifeOptions, minify: true, metafile: shouldVisualize }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await Promise.all(buildConfigs.map((option) => build(getBuildConfig(option))));
|
||||||
|
|
||||||
|
if (shouldVisualize) {
|
||||||
|
for (const { metafile } of results) {
|
||||||
|
if (!metafile) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const fileName = Object.keys(metafile.outputs)
|
||||||
|
.filter((file) => !file.includes('chunks') && file.endsWith('js'))[0]
|
||||||
|
.replace('dist/', '');
|
||||||
|
// Upload metafile into https://esbuild.github.io/analyze/
|
||||||
|
await writeFile(`stats/${fileName}.meta.json`, JSON.stringify(metafile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handler = (e) => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
await generateLangium();
|
||||||
|
await mkdir('stats').catch(() => {});
|
||||||
|
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||||
|
// it should build `parser` before `mermaid` because it's a dependency
|
||||||
|
for (const pkg of packageNames) {
|
||||||
|
await buildPackage(pkg).catch(handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void main();
|
15
.esbuild/jisonPlugin.ts
Normal file
15
.esbuild/jisonPlugin.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { readFile } from 'node:fs/promises';
|
||||||
|
import { transformJison } from '../.build/jisonTransformer.js';
|
||||||
|
import { Plugin } from 'esbuild';
|
||||||
|
|
||||||
|
export const jisonPlugin: Plugin = {
|
||||||
|
name: 'jison',
|
||||||
|
setup(build) {
|
||||||
|
build.onLoad({ filter: /\.jison$/ }, async (args) => {
|
||||||
|
// Load the file from the file system
|
||||||
|
const source = await readFile(args.path, 'utf8');
|
||||||
|
const contents = transformJison(source);
|
||||||
|
return { contents, warnings: [] };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
35
.esbuild/jsonSchemaPlugin.ts
Normal file
35
.esbuild/jsonSchemaPlugin.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import type { JSONSchemaType } from 'ajv/dist/2019.js';
|
||||||
|
import type { MermaidConfig } from '../packages/mermaid/src/config.type.js';
|
||||||
|
import { readFile } from 'node:fs/promises';
|
||||||
|
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ESBuild plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||||
|
*
|
||||||
|
* Use `my-example.schema.yaml?only-defaults=true` to only load the default values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const jsonSchemaPlugin = {
|
||||||
|
name: 'json-schema-plugin',
|
||||||
|
setup(build) {
|
||||||
|
let schema: JSONSchemaType<MermaidConfig> | undefined = undefined;
|
||||||
|
let content = '';
|
||||||
|
|
||||||
|
build.onLoad({ filter: /config\.schema\.yaml$/ }, async (args) => {
|
||||||
|
// Load the file from the file system
|
||||||
|
const source = await readFile(args.path, 'utf8');
|
||||||
|
const resolvedSchema: JSONSchemaType<MermaidConfig> =
|
||||||
|
content === source && schema ? schema : loadSchema(source, args.path);
|
||||||
|
if (content !== source) {
|
||||||
|
content = source;
|
||||||
|
schema = resolvedSchema;
|
||||||
|
}
|
||||||
|
const contents = args.suffix.includes('only-defaults')
|
||||||
|
? getDefaults(resolvedSchema)
|
||||||
|
: getSchema(resolvedSchema);
|
||||||
|
return { contents, warnings: [] };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default jsonSchemaPlugin;
|
102
.esbuild/server.ts
Normal file
102
.esbuild/server.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import express from 'express';
|
||||||
|
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 { generateLangium } from '../.build/generateLangium.js';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
|
||||||
|
const configs = Object.values(packageOptions).map(({ packageName }) =>
|
||||||
|
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: packageName })
|
||||||
|
);
|
||||||
|
const mermaidIIFEConfig = getBuildConfig({
|
||||||
|
...defaultOptions,
|
||||||
|
minify: false,
|
||||||
|
core: false,
|
||||||
|
entryName: 'mermaid',
|
||||||
|
format: 'iife',
|
||||||
|
});
|
||||||
|
configs.push(mermaidIIFEConfig);
|
||||||
|
|
||||||
|
const contexts = await Promise.all(configs.map((config) => context(config)));
|
||||||
|
|
||||||
|
const rebuildAll = async () => {
|
||||||
|
console.time('Rebuild time');
|
||||||
|
await Promise.all(contexts.map((ctx) => ctx.rebuild())).catch((e) => console.error(e));
|
||||||
|
console.timeEnd('Rebuild time');
|
||||||
|
};
|
||||||
|
|
||||||
|
let clients: { id: number; response: Response }[] = [];
|
||||||
|
function eventsHandler(request: Request, response: Response, next: NextFunction) {
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
Connection: 'keep-alive',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
};
|
||||||
|
response.writeHead(200, headers);
|
||||||
|
const clientId = Date.now();
|
||||||
|
clients.push({
|
||||||
|
id: clientId,
|
||||||
|
response,
|
||||||
|
});
|
||||||
|
request.on('close', () => {
|
||||||
|
clients = clients.filter((client) => client.id !== clientId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeoutId: NodeJS.Timeout | undefined = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debounce file change events to avoid rebuilding multiple times.
|
||||||
|
*/
|
||||||
|
function handleFileChange() {
|
||||||
|
if (timeoutId !== undefined) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
timeoutId = setTimeout(async () => {
|
||||||
|
await rebuildAll();
|
||||||
|
sendEventsToAll();
|
||||||
|
timeoutId = undefined;
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendEventsToAll() {
|
||||||
|
clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createServer() {
|
||||||
|
await generateLangium();
|
||||||
|
handleFileChange();
|
||||||
|
const app = express();
|
||||||
|
chokidar
|
||||||
|
.watch('**/src/**/*.{js,ts,langium,yaml,json}', {
|
||||||
|
ignoreInitial: true,
|
||||||
|
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
|
||||||
|
})
|
||||||
|
.on('all', async (event, path) => {
|
||||||
|
// Ignore other events.
|
||||||
|
if (!['add', 'change'].includes(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (/\.langium$/.test(path)) {
|
||||||
|
await generateLangium();
|
||||||
|
}
|
||||||
|
console.log(`${path} changed. Rebuilding...`);
|
||||||
|
handleFileChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
|
app.get('/events', eventsHandler);
|
||||||
|
for (const { packageName } of Object.values(packageOptions)) {
|
||||||
|
app.use(express.static(`./packages/${packageName}/dist`));
|
||||||
|
}
|
||||||
|
app.use(express.static('demos'));
|
||||||
|
app.use(express.static('cypress/platform'));
|
||||||
|
|
||||||
|
app.listen(9000, () => {
|
||||||
|
console.log(`Listening on http://localhost:9000`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createServer();
|
101
.esbuild/util.ts
Normal file
101
.esbuild/util.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { resolve } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import type { BuildOptions } from 'esbuild';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
import { jisonPlugin } from './jisonPlugin.js';
|
||||||
|
|
||||||
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||||
|
|
||||||
|
export interface MermaidBuildOptions {
|
||||||
|
minify: boolean;
|
||||||
|
core: boolean;
|
||||||
|
metafile: boolean;
|
||||||
|
format: 'esm' | 'iife';
|
||||||
|
entryName: keyof typeof packageOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName'> = {
|
||||||
|
minify: false,
|
||||||
|
metafile: false,
|
||||||
|
core: false,
|
||||||
|
format: 'esm',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const buildOptions = (override: BuildOptions): BuildOptions => {
|
||||||
|
return {
|
||||||
|
bundle: true,
|
||||||
|
minify: true,
|
||||||
|
keepNames: true,
|
||||||
|
platform: 'browser',
|
||||||
|
tsconfig: 'tsconfig.json',
|
||||||
|
resolveExtensions: ['.ts', '.js', '.json', '.jison', '.yaml'],
|
||||||
|
external: ['require', 'fs', 'path'],
|
||||||
|
outdir: 'dist',
|
||||||
|
plugins: [jisonPlugin, jsonSchemaPlugin],
|
||||||
|
sourcemap: 'external',
|
||||||
|
...override,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
|
||||||
|
if (core) {
|
||||||
|
fileName += '.core';
|
||||||
|
} else if (format === 'esm') {
|
||||||
|
fileName += '.esm';
|
||||||
|
}
|
||||||
|
if (minify) {
|
||||||
|
fileName += '.min';
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
|
||||||
|
const { core, entryName, metafile, format, minify } = options;
|
||||||
|
const external: string[] = ['require', 'fs', 'path'];
|
||||||
|
const { name, file, packageName } = packageOptions[entryName];
|
||||||
|
const outFileName = getFileName(name, options);
|
||||||
|
let output: BuildOptions = buildOptions({
|
||||||
|
absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
|
||||||
|
entryPoints: {
|
||||||
|
[outFileName]: `src/${file}`,
|
||||||
|
},
|
||||||
|
metafile,
|
||||||
|
minify,
|
||||||
|
logLevel: 'info',
|
||||||
|
chunkNames: `chunks/${outFileName}/[name]-[hash]`,
|
||||||
|
define: {
|
||||||
|
'import.meta.vitest': 'undefined',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (core) {
|
||||||
|
const { dependencies } = JSON.parse(
|
||||||
|
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
|
||||||
|
);
|
||||||
|
// Core build is used to generate file without bundled dependencies.
|
||||||
|
// This is used by downstream projects to bundle dependencies themselves.
|
||||||
|
// Ignore dependencies and any dependencies of dependencies
|
||||||
|
external.push(...Object.keys(dependencies));
|
||||||
|
output.external = external;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === 'iife') {
|
||||||
|
output.format = 'iife';
|
||||||
|
output.splitting = false;
|
||||||
|
output.globalName = '__esbuild_esm_mermaid';
|
||||||
|
// Workaround for removing the .default access in esbuild IIFE.
|
||||||
|
// https://github.com/mermaid-js/mermaid/pull/4109#discussion_r1292317396
|
||||||
|
output.footer = {
|
||||||
|
js: 'globalThis.mermaid = globalThis.__esbuild_esm_mermaid.default;',
|
||||||
|
};
|
||||||
|
output.outExtension = { '.js': '.js' };
|
||||||
|
} else {
|
||||||
|
output.format = 'esm';
|
||||||
|
output.splitting = true;
|
||||||
|
output.outExtension = { '.js': '.mjs' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
@ -6,3 +6,6 @@ cypress/plugins/index.js
|
|||||||
coverage
|
coverage
|
||||||
*.json
|
*.json
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# autogenereated by langium-cli
|
||||||
|
generated/
|
||||||
|
1
.github/codecov.yaml
vendored
1
.github/codecov.yaml
vendored
@ -15,3 +15,4 @@ coverage:
|
|||||||
# Turing off for now as code coverage isn't stable and causes unnecessary build failures.
|
# Turing off for now as code coverage isn't stable and causes unnecessary build failures.
|
||||||
# default:
|
# default:
|
||||||
# threshold: 2%
|
# threshold: 2%
|
||||||
|
patch: off
|
||||||
|
5
.github/lychee.toml
vendored
5
.github/lychee.toml
vendored
@ -38,7 +38,10 @@ exclude = [
|
|||||||
"https://discord.gg",
|
"https://discord.gg",
|
||||||
|
|
||||||
# BundlePhobia has frequent downtime
|
# BundlePhobia has frequent downtime
|
||||||
"https://bundlephobia.com"
|
"https://bundlephobia.com",
|
||||||
|
|
||||||
|
# Chrome webstore redirect issue
|
||||||
|
"https://chromewebstore.google.com"
|
||||||
]
|
]
|
||||||
|
|
||||||
# Exclude all private IPs from checking.
|
# Exclude all private IPs from checking.
|
||||||
|
34
.github/workflows/e2e.yml
vendored
34
.github/workflows/e2e.yml
vendored
@ -48,11 +48,26 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
ref: ${{ env.targetHash }}
|
ref: ${{ env.targetHash }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||||
|
uses: cypress-io/github-action@v6
|
||||||
|
with:
|
||||||
|
# just perform install
|
||||||
|
runTests: false
|
||||||
|
|
||||||
|
- name: Calculate bundle size
|
||||||
|
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true'}}
|
||||||
|
run: |
|
||||||
|
pnpm run build:viz
|
||||||
|
mkdir -p cypress/snapshots/stats/base
|
||||||
|
mv stats cypress/snapshots/stats/base
|
||||||
|
|
||||||
- name: Cypress run
|
- name: Cypress run
|
||||||
uses: cypress-io/github-action@v4
|
uses: cypress-io/github-action@v6
|
||||||
id: cypress-snapshot-gen
|
id: cypress-snapshot-gen
|
||||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||||
with:
|
with:
|
||||||
|
install: false
|
||||||
start: pnpm run dev
|
start: pnpm run dev
|
||||||
wait-on: 'http://localhost:9000'
|
wait-on: 'http://localhost:9000'
|
||||||
browser: chrome
|
browser: chrome
|
||||||
@ -86,15 +101,30 @@ jobs:
|
|||||||
path: ./cypress/snapshots
|
path: ./cypress/snapshots
|
||||||
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
uses: cypress-io/github-action@v6
|
||||||
|
with:
|
||||||
|
runTests: false
|
||||||
|
|
||||||
|
- name: Output size diff
|
||||||
|
if: ${{ matrix.containers == 1 }}
|
||||||
|
run: |
|
||||||
|
pnpm run build:viz
|
||||||
|
mv stats cypress/snapshots/stats/head
|
||||||
|
echo '## Bundle size difference' >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
echo '' >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
npx tsx scripts/size.ts >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
# Install NPM dependencies, cache them correctly
|
# Install NPM dependencies, cache them correctly
|
||||||
# and run all Cypress tests
|
# and run all Cypress tests
|
||||||
- name: Cypress run
|
- name: Cypress run
|
||||||
uses: cypress-io/github-action@v4
|
uses: cypress-io/github-action@v6
|
||||||
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.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||||
with:
|
with:
|
||||||
|
install: false
|
||||||
start: pnpm run dev:coverage
|
start: pnpm run dev:coverage
|
||||||
wait-on: 'http://localhost:9000'
|
wait-on: 'http://localhost:9000'
|
||||||
browser: chrome
|
browser: chrome
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -46,4 +46,8 @@ stats/
|
|||||||
|
|
||||||
demos/dev/**
|
demos/dev/**
|
||||||
!/demos/dev/example.html
|
!/demos/dev/example.html
|
||||||
|
!/demos/dev/reload.js
|
||||||
tsx-0/**
|
tsx-0/**
|
||||||
|
|
||||||
|
# autogenereated by langium-cli
|
||||||
|
generated/
|
@ -11,6 +11,8 @@ stats
|
|||||||
.nyc_output
|
.nyc_output
|
||||||
# Autogenerated by `pnpm run --filter mermaid types:build-config`
|
# Autogenerated by `pnpm run --filter mermaid types:build-config`
|
||||||
packages/mermaid/src/config.type.ts
|
packages/mermaid/src/config.type.ts
|
||||||
|
# autogenereated by langium-cli
|
||||||
|
generated/
|
||||||
# Ignore the files creates in /demos/dev except for example.html
|
# Ignore the files creates in /demos/dev except for example.html
|
||||||
demos/dev/**
|
demos/dev/**
|
||||||
!/demos/dev/example.html
|
!/demos/dev/example.html
|
||||||
|
@ -3,11 +3,12 @@ import { resolve } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import jisonPlugin from './jisonPlugin.js';
|
import jisonPlugin from './jisonPlugin.js';
|
||||||
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
|
||||||
import { readFileSync } from 'fs';
|
|
||||||
import typescript from '@rollup/plugin-typescript';
|
import typescript from '@rollup/plugin-typescript';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
|
import type { TemplateType } from 'rollup-plugin-visualizer/dist/plugin/template-types.js';
|
||||||
import istanbul from 'vite-plugin-istanbul';
|
import istanbul from 'vite-plugin-istanbul';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
import { generateLangium } from '../.build/generateLangium.js';
|
||||||
|
|
||||||
const visualize = process.argv.includes('--visualize');
|
const visualize = process.argv.includes('--visualize');
|
||||||
const watch = process.argv.includes('--watch');
|
const watch = process.argv.includes('--watch');
|
||||||
@ -36,24 +37,6 @@ const visualizerOptions = (packageName: string, core = false): PluginOption[] =>
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const packageOptions = {
|
|
||||||
mermaid: {
|
|
||||||
name: 'mermaid',
|
|
||||||
packageName: 'mermaid',
|
|
||||||
file: 'mermaid.ts',
|
|
||||||
},
|
|
||||||
'mermaid-example-diagram': {
|
|
||||||
name: 'mermaid-example-diagram',
|
|
||||||
packageName: 'mermaid-example-diagram',
|
|
||||||
file: 'detector.ts',
|
|
||||||
},
|
|
||||||
'mermaid-zenuml': {
|
|
||||||
name: 'mermaid-zenuml',
|
|
||||||
packageName: 'mermaid-zenuml',
|
|
||||||
file: 'detector.ts',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
interface BuildOptions {
|
interface BuildOptions {
|
||||||
minify: boolean | 'esbuild';
|
minify: boolean | 'esbuild';
|
||||||
core?: boolean;
|
core?: boolean;
|
||||||
@ -72,34 +55,8 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
sourcemap,
|
sourcemap,
|
||||||
entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
|
entryFileNames: `${name}.esm${minify ? '.min' : ''}.mjs`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name,
|
|
||||||
format: 'umd',
|
|
||||||
sourcemap,
|
|
||||||
entryFileNames: `${name}${minify ? '.min' : ''}.js`,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (core) {
|
|
||||||
const { dependencies } = JSON.parse(
|
|
||||||
readFileSync(resolve(__dirname, `../packages/${packageName}/package.json`), 'utf-8')
|
|
||||||
);
|
|
||||||
// Core build is used to generate file without bundled dependencies.
|
|
||||||
// This is used by downstream projects to bundle dependencies themselves.
|
|
||||||
// Ignore dependencies and any dependencies of dependencies
|
|
||||||
// Adapted from the RegEx used by `rollup-plugin-node`
|
|
||||||
external.push(new RegExp('^(?:' + Object.keys(dependencies).join('|') + ')(?:/.+)?$'));
|
|
||||||
// This needs to be an array. Otherwise vite will build esm & umd with same name and overwrite esm with umd.
|
|
||||||
output = [
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
format: 'esm',
|
|
||||||
sourcemap,
|
|
||||||
entryFileNames: `${name}.core.mjs`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
const config: InlineConfig = {
|
const config: InlineConfig = {
|
||||||
configFile: false,
|
configFile: false,
|
||||||
build: {
|
build: {
|
||||||
@ -129,7 +86,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
|
// @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__'],
|
exclude: ['node_modules', 'test/', '__mocks__', 'generated'],
|
||||||
extension: ['.js', '.ts'],
|
extension: ['.js', '.ts'],
|
||||||
requireEnv: true,
|
requireEnv: true,
|
||||||
forceBuildInstrument: coverage,
|
forceBuildInstrument: coverage,
|
||||||
@ -149,24 +106,28 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
|
|
||||||
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
||||||
await build(getBuildConfig({ minify: false, entryName }));
|
await build(getBuildConfig({ minify: false, entryName }));
|
||||||
await build(getBuildConfig({ minify: 'esbuild', entryName }));
|
|
||||||
await build(getBuildConfig({ minify: false, core: true, entryName }));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||||
for (const pkg of packageNames.filter((pkg) => !mermaidOnly || pkg === 'mermaid')) {
|
for (const pkg of packageNames.filter(
|
||||||
|
(pkg) => !mermaidOnly || pkg === 'mermaid' || pkg === 'parser'
|
||||||
|
)) {
|
||||||
await buildPackage(pkg);
|
await buildPackage(pkg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
await generateLangium();
|
||||||
|
|
||||||
if (watch) {
|
if (watch) {
|
||||||
|
await build(getBuildConfig({ minify: false, watch, core: false, entryName: 'parser' }));
|
||||||
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
|
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
|
||||||
if (!mermaidOnly) {
|
if (!mermaidOnly) {
|
||||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
|
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
|
||||||
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-zenuml' }));
|
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, core: true, entryName: 'mermaid' }));
|
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));
|
||||||
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
|
await build(getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { transformJison } from './jisonTransformer.js';
|
import { transformJison } from '../.build/jisonTransformer.js';
|
||||||
|
|
||||||
const fileRegex = /\.(jison)$/;
|
const fileRegex = /\.(jison)$/;
|
||||||
|
|
||||||
export default function jison() {
|
export default function jison() {
|
||||||
return {
|
return {
|
||||||
name: 'jison',
|
name: 'jison',
|
||||||
|
|
||||||
transform(src: string, id: string) {
|
transform(src: string, id: string) {
|
||||||
if (fileRegex.test(id)) {
|
if (fileRegex.test(id)) {
|
||||||
return {
|
return {
|
||||||
|
@ -1,110 +1,5 @@
|
|||||||
import { load, JSON_SCHEMA } from 'js-yaml';
|
|
||||||
import assert from 'node:assert';
|
|
||||||
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
|
|
||||||
import { PluginOption } from 'vite';
|
import { PluginOption } from 'vite';
|
||||||
|
import { getDefaults, getSchema, loadSchema } from '../.build/jsonSchema.js';
|
||||||
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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',
|
|
||||||
'block',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate default values from the JSON Schema.
|
|
||||||
*
|
|
||||||
* AJV does not support nested default values yet (or default values with $ref),
|
|
||||||
* so we need to manually find them (this may be fixed in ajv v9).
|
|
||||||
*
|
|
||||||
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
|
|
||||||
* @returns The default mermaid config object.
|
|
||||||
*/
|
|
||||||
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
|
|
||||||
const ajv = new Ajv2019({
|
|
||||||
useDefaults: true,
|
|
||||||
allowUnionTypes: true,
|
|
||||||
strict: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
ajv.addKeyword({
|
|
||||||
keyword: 'meta:enum', // used by jsonschema2md
|
|
||||||
errors: false,
|
|
||||||
});
|
|
||||||
ajv.addKeyword({
|
|
||||||
keyword: 'tsType', // used by json-schema-to-typescript
|
|
||||||
errors: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
|
|
||||||
// (may be fixed in v9) so we need to manually use sub-schemas
|
|
||||||
const mermaidDefaultConfig = {};
|
|
||||||
|
|
||||||
assert.ok(mermaidConfigSchema.$defs);
|
|
||||||
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
|
|
||||||
|
|
||||||
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
|
|
||||||
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
|
|
||||||
const [root, defs, defName] = subSchemaRef.split('/');
|
|
||||||
assert.strictEqual(root, '#');
|
|
||||||
assert.strictEqual(defs, '$defs');
|
|
||||||
const subSchema = {
|
|
||||||
$schema: mermaidConfigSchema.$schema,
|
|
||||||
$defs: mermaidConfigSchema.$defs,
|
|
||||||
...mermaidConfigSchema.$defs[defName],
|
|
||||||
} as JSONSchemaType<BaseDiagramConfig>;
|
|
||||||
|
|
||||||
const validate = ajv.compile(subSchema);
|
|
||||||
|
|
||||||
mermaidDefaultConfig[key] = {};
|
|
||||||
|
|
||||||
for (const required of subSchema.required ?? []) {
|
|
||||||
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
|
|
||||||
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!validate(mermaidDefaultConfig[key])) {
|
|
||||||
throw new Error(
|
|
||||||
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
|
|
||||||
validate.errors,
|
|
||||||
undefined,
|
|
||||||
2
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const validate = ajv.compile(mermaidConfigSchema);
|
|
||||||
|
|
||||||
if (!validate(mermaidDefaultConfig)) {
|
|
||||||
throw new Error(
|
|
||||||
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
|
|
||||||
validate.errors,
|
|
||||||
undefined,
|
|
||||||
2
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mermaidDefaultConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
|
||||||
@ -121,32 +16,13 @@ export default function jsonSchemaPlugin(): PluginOption {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idAsUrl.searchParams.get('only-defaults')) {
|
const jsonSchema = loadSchema(src, idAsUrl.pathname);
|
||||||
const jsonSchema = load(src, {
|
return {
|
||||||
filename: idAsUrl.pathname,
|
code: idAsUrl.searchParams.get('only-defaults')
|
||||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
? getDefaults(jsonSchema)
|
||||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
: getSchema(jsonSchema),
|
||||||
schema: JSON_SCHEMA,
|
map: null, // no source map
|
||||||
}) as JSONSchemaType<MermaidConfig>;
|
};
|
||||||
return {
|
|
||||||
code: `export default ${JSON.stringify(generateDefaults(jsonSchema), undefined, 2)};`,
|
|
||||||
map: null, // no source map
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: `export default ${JSON.stringify(
|
|
||||||
load(src, {
|
|
||||||
filename: idAsUrl.pathname,
|
|
||||||
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
|
|
||||||
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
|
|
||||||
schema: JSON_SCHEMA,
|
|
||||||
}),
|
|
||||||
undefined,
|
|
||||||
2
|
|
||||||
)};`,
|
|
||||||
map: null, // provide source map if available
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { createServer as createViteServer } from 'vite';
|
import { createServer as createViteServer } from 'vite';
|
||||||
|
import { packageOptions } from '../.build/common.js';
|
||||||
|
|
||||||
async function createServer() {
|
async function createServer() {
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -14,9 +15,9 @@ async function createServer() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(express.static('./packages/mermaid/dist'));
|
for (const { packageName } of Object.values(packageOptions)) {
|
||||||
app.use(express.static('./packages/mermaid-zenuml/dist'));
|
app.use(express.static(`./packages/${packageName}/dist`));
|
||||||
app.use(express.static('./packages/mermaid-example-diagram/dist'));
|
}
|
||||||
app.use(vite.middlewares);
|
app.use(vite.middlewares);
|
||||||
app.use(express.static('demos'));
|
app.use(express.static('demos'));
|
||||||
app.use(express.static('cypress/platform'));
|
app.use(express.static('cypress/platform'));
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
FROM node:20.11.0-alpine3.19 AS base
|
FROM node:20.11.1-alpine3.19 AS base
|
||||||
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
|
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked C4Context diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const drawPersonOrSystemArray = vi.fn();
|
|
||||||
export const drawBoundary = vi.fn();
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
drawPersonOrSystemArray,
|
|
||||||
drawBoundary,
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked class diagram v2 renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked class diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
// DO NOT delete this file. It is used by vitest to mock the dagre-d3 module.
|
|
@ -1,3 +0,0 @@
|
|||||||
module.exports = function (txt: string) {
|
|
||||||
return txt;
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked er diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,24 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked flow (flowchart) diagram v2 renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
export const addVertices = vi.fn();
|
|
||||||
export const addEdges = vi.fn();
|
|
||||||
export const getClasses = vi.fn().mockImplementation(() => {
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
addVertices,
|
|
||||||
addEdges,
|
|
||||||
getClasses,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked gantt diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked git (graph) diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked pie (picChart) diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,8 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked pie (picChart) diagram renderer
|
|
||||||
*/
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
const draw = vi.fn().mockImplementation(() => '');
|
|
||||||
|
|
||||||
export const renderer = { draw };
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked requirement diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked Sankey diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked sequence diagram renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const bounds = vi.fn();
|
|
||||||
export const drawActors = vi.fn();
|
|
||||||
export const drawActorsPopup = vi.fn();
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
bounds,
|
|
||||||
drawActors,
|
|
||||||
drawActorsPopup,
|
|
||||||
setConf,
|
|
||||||
draw,
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Mocked state diagram v2 renderer
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { vi } from 'vitest';
|
|
||||||
|
|
||||||
export const setConf = vi.fn();
|
|
||||||
export const getClasses = vi.fn().mockImplementation(() => {
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
export const stateDomId = vi.fn().mockImplementation(() => {
|
|
||||||
return 'mocked-stateDiagram-stateDomId';
|
|
||||||
});
|
|
||||||
export const draw = vi.fn().mockImplementation(() => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
|
||||||
setConf,
|
|
||||||
getClasses,
|
|
||||||
draw,
|
|
||||||
};
|
|
14
cypress/integration/other/flowchart-elk.spec.js
Normal file
14
cypress/integration/other/flowchart-elk.spec.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.ts';
|
||||||
|
|
||||||
|
describe('Flowchart elk', () => {
|
||||||
|
it('should use dagre as fallback', () => {
|
||||||
|
urlSnapshotTest('http://localhost:9000/flow-elk.html', {
|
||||||
|
name: 'flow-elk fallback to dagre',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should allow overriding with external package', () => {
|
||||||
|
urlSnapshotTest('http://localhost:9000/flow-elk.html?elk=true', {
|
||||||
|
name: 'flow-elk overriding dagre with elk',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
11
cypress/integration/other/iife.spec.js
Normal file
11
cypress/integration/other/iife.spec.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
describe('IIFE', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('http://localhost:9000/iife.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render when using mermaid.min.js', () => {
|
||||||
|
cy.window().should('have.property', 'rendered', true);
|
||||||
|
cy.get('svg').should('be.visible');
|
||||||
|
cy.get('#d2').should('contain', 'Hello');
|
||||||
|
});
|
||||||
|
});
|
@ -1,16 +0,0 @@
|
|||||||
describe('Sequencediagram', () => {
|
|
||||||
it('should render a simple sequence diagrams', () => {
|
|
||||||
const url = 'http://localhost:9000/webpackUsage.html';
|
|
||||||
|
|
||||||
cy.visit(url);
|
|
||||||
cy.get('body').find('svg').should('have.length', 1);
|
|
||||||
});
|
|
||||||
it('should handle html escapings properly', () => {
|
|
||||||
const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
|
|
||||||
|
|
||||||
cy.visit(url);
|
|
||||||
cy.get('body').find('svg').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
|
|
||||||
});
|
|
||||||
});
|
|
67
cypress/integration/rendering/packet.spec.ts
Normal file
67
cypress/integration/rendering/packet.spec.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
|
describe('packet structure', () => {
|
||||||
|
it('should render a simple packet diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`packet-beta
|
||||||
|
title Hello world
|
||||||
|
0-10: "hello"
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a complex packet diagram', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a complex packet diagram with showBits false', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
---
|
||||||
|
title: "Packet Diagram"
|
||||||
|
config:
|
||||||
|
packet:
|
||||||
|
showBits: false
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,7 +1,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<script src="./viewer.js" type="module"></script>
|
<script type="module" src="./viewer.js"></script>
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
|
@ -11,8 +11,7 @@ example-diagram
|
|||||||
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
|
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
|
||||||
<!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
|
<!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import exampleDiagram from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
|
import exampleDiagram from './mermaid-example-diagram.esm.mjs';
|
||||||
// import example from '../../packages/mermaid-example-diagram/src/detector';
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
|
||||||
await mermaid.registerExternalDiagrams([exampleDiagram]);
|
await mermaid.registerExternalDiagrams([exampleDiagram]);
|
||||||
|
28
cypress/platform/flow-elk.html
Normal file
28
cypress/platform/flow-elk.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<pre class="mermaid">
|
||||||
|
flowchart-elk
|
||||||
|
a[hello] --> b[world]
|
||||||
|
b --> c{test}
|
||||||
|
c --> one
|
||||||
|
c --> two
|
||||||
|
c --> three
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
import elk from './mermaid-flowchart-elk.esm.min.mjs';
|
||||||
|
if (window.location.search.includes('elk')) {
|
||||||
|
await mermaid.registerExternalDiagrams([elk]);
|
||||||
|
}
|
||||||
|
mermaid.initialize({
|
||||||
|
logLevel: 3,
|
||||||
|
startOnLoad: false,
|
||||||
|
});
|
||||||
|
await mermaid.run();
|
||||||
|
if (window.Cypress) {
|
||||||
|
window.rendered = true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
29
cypress/platform/iife.html
Normal file
29
cypress/platform/iife.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<pre id="diagram" class="mermaid">
|
||||||
|
graph TB
|
||||||
|
a --> b
|
||||||
|
a --> c
|
||||||
|
b --> d
|
||||||
|
c --> d
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div id="d2"></div>
|
||||||
|
|
||||||
|
<script src="/mermaid.min.js"></script>
|
||||||
|
<script>
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: true,
|
||||||
|
});
|
||||||
|
const value = `graph TD\nHello --> World`;
|
||||||
|
const el = document.getElementById('d2');
|
||||||
|
mermaid.render('did', value).then(({ svg }) => {
|
||||||
|
console.log(svg);
|
||||||
|
el.innerHTML = svg;
|
||||||
|
if (window.Cypress) {
|
||||||
|
window.rendered = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -17,20 +17,20 @@
|
|||||||
graph TB
|
graph TB
|
||||||
Function-->URL
|
Function-->URL
|
||||||
click Function clickByFlow "Add a div"
|
click Function clickByFlow "Add a div"
|
||||||
click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
click URL "http://localhost:9000/info.html" "Visit <strong>mermaid docs</strong>"
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="FirstLine" class="mermaid2">
|
<pre id="FirstLine" class="mermaid2">
|
||||||
graph TB
|
graph TB
|
||||||
1Function-->2URL
|
1Function-->2URL
|
||||||
click 1Function clickByFlow "Add a div"
|
click 1Function clickByFlow "Add a div"
|
||||||
click 2URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
|
click 2URL "http://localhost:9000/info.html" "Visit <strong>mermaid docs</strong>"
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="FirstLine" class="mermaid2">
|
<pre id="FirstLine" class="mermaid2">
|
||||||
classDiagram
|
classDiagram
|
||||||
class Test
|
class Test
|
||||||
class ShapeLink
|
class ShapeLink
|
||||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
link ShapeLink "http://localhost:9000/info.html" "This is a tooltip for a link"
|
||||||
class ShapeCallback
|
class ShapeCallback
|
||||||
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
|
||||||
</pre>
|
</pre>
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<pre id="FirstLine" class="mermaid">
|
<pre id="FirstLine" class="mermaid">
|
||||||
classDiagram-v2
|
classDiagram-v2
|
||||||
class ShapeLink
|
class ShapeLink
|
||||||
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
|
link ShapeLink "http://localhost:9000/info.html" "This is a tooltip for a link"
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -77,7 +77,7 @@
|
|||||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||||
Calling a Callback with args :cl3, after cl1, 3d
|
Calling a Callback with args :cl3, after cl1, 3d
|
||||||
|
|
||||||
click cl1 href "http://localhost:9000/webpackUsage.html"
|
click cl1 href "http://localhost:9000/info.html"
|
||||||
click cl2 call clickByGantt()
|
click cl2 call clickByGantt()
|
||||||
click cl3 call clickByGantt("test1", test2, test3)
|
click cl3 call clickByGantt("test1", test2, test3)
|
||||||
|
|
||||||
@ -102,9 +102,15 @@
|
|||||||
div.className = 'created-by-gant-click';
|
div.className = 'created-by-gant-click';
|
||||||
div.style = 'padding: 20px; background: green; color: white;';
|
div.style = 'padding: 20px; background: green; color: white;';
|
||||||
div.innerText = 'Clicked By Gant';
|
div.innerText = 'Clicked By Gant';
|
||||||
if (arg1) div.innerText += ' ' + arg1;
|
if (arg1) {
|
||||||
if (arg2) div.innerText += ' ' + arg2;
|
div.innerText += ' ' + arg1;
|
||||||
if (arg3) div.innerText += ' ' + arg3;
|
}
|
||||||
|
if (arg2) {
|
||||||
|
div.innerText += ' ' + arg2;
|
||||||
|
}
|
||||||
|
if (arg3) {
|
||||||
|
div.innerText += ' ' + arg3;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import mermaid2 from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
import externalExample from '../../packages/mermaid-example-diagram/dist/mermaid-example-diagram.core.mjs';
|
import externalExample from './mermaid-example-diagram.esm.mjs';
|
||||||
import zenUml from '../../packages/mermaid-zenuml/dist/mermaid-zenuml.core.mjs';
|
import zenUml from './mermaid-zenuml.esm.mjs';
|
||||||
|
|
||||||
function b64ToUtf8(str) {
|
function b64ToUtf8(str) {
|
||||||
return decodeURIComponent(escape(window.atob(str)));
|
return decodeURIComponent(escape(window.atob(str)));
|
||||||
@ -45,9 +45,9 @@ const contentLoaded = async function () {
|
|||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
await mermaid2.registerExternalDiagrams([externalExample, zenUml]);
|
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
||||||
mermaid2.initialize(graphObj.mermaid);
|
mermaid.initialize(graphObj.mermaid);
|
||||||
await mermaid2.run();
|
await mermaid.run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,18 +95,14 @@ const contentLoadedApi = async function () {
|
|||||||
divs[i] = div;
|
divs[i] = div;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultE2eCnf = { theme: 'forest' };
|
const defaultE2eCnf = { theme: 'forest', startOnLoad: false };
|
||||||
|
|
||||||
const cnf = merge(defaultE2eCnf, graphObj.mermaid);
|
const cnf = merge(defaultE2eCnf, graphObj.mermaid);
|
||||||
|
|
||||||
mermaid2.initialize(cnf);
|
mermaid.initialize(cnf);
|
||||||
|
|
||||||
for (let i = 0; i < numCodes; i++) {
|
for (let i = 0; i < numCodes; i++) {
|
||||||
const { svg, bindFunctions } = await mermaid2.render(
|
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
||||||
'newid' + i,
|
|
||||||
graphObj.code[i],
|
|
||||||
divs[i]
|
|
||||||
);
|
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
bindFunctions(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
@ -114,18 +110,21 @@ const contentLoadedApi = async function () {
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.id = 'block';
|
div.id = 'block';
|
||||||
div.className = 'mermaid';
|
div.className = 'mermaid';
|
||||||
console.warn('graphObj.mermaid', graphObj.mermaid);
|
console.warn('graphObj', graphObj);
|
||||||
document.getElementsByTagName('body')[0].appendChild(div);
|
document.getElementsByTagName('body')[0].appendChild(div);
|
||||||
mermaid2.initialize(graphObj.mermaid);
|
mermaid.initialize(graphObj.mermaid);
|
||||||
|
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
||||||
const { svg, bindFunctions } = await mermaid2.render('newid', graphObj.code, div);
|
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
|
console.log(div.innerHTML);
|
||||||
bindFunctions(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: false,
|
||||||
|
});
|
||||||
/*!
|
/*!
|
||||||
* Wait for document loaded before starting the execution
|
* Wait for document loaded before starting the execution
|
||||||
*/
|
*/
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
/* .mermaid {
|
|
||||||
font-family: "trebuchet ms", verdana, arial;;
|
|
||||||
} */
|
|
||||||
/* .mermaid {
|
|
||||||
font-family: 'arial';
|
|
||||||
} */
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="graph-to-be"></div>
|
|
||||||
<script type="module" charset="utf-8">
|
|
||||||
import './bundle-test.js';
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,6 +1,5 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="./viewer.js" type="module"></script>
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
.malware {
|
.malware {
|
||||||
@ -33,12 +32,6 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<script type="module" src="./viewer.js"></script>
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
mermaid.initialize({
|
|
||||||
startOnLoad: false,
|
|
||||||
useMaxWidth: true,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,6 +3,22 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Mermaid development page</title>
|
<title>Mermaid development page</title>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
#code {
|
||||||
|
max-width: 30vw;
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dynamicDiagram {
|
||||||
|
padding-left: 2em;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
@ -13,22 +29,37 @@ graph TB
|
|||||||
c --> d
|
c --> d
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<div id="dynamicDiagram"></div>
|
<hr />
|
||||||
|
Type code to view diagram:
|
||||||
|
<div class="container">
|
||||||
|
<textarea name="code" id="code" cols="30" rows="10"></textarea>
|
||||||
|
<div id="dynamicDiagram"></div>
|
||||||
|
</div>
|
||||||
|
<pre class="mermaid">info</pre>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from '/mermaid.esm.mjs';
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
mermaid.parseError = function (err, hash) {
|
async function render(str) {
|
||||||
console.error('Mermaid error: ', err);
|
const { svg } = await mermaid.render('dynamic', str);
|
||||||
};
|
document.getElementById('dynamicDiagram').innerHTML = svg;
|
||||||
|
}
|
||||||
|
const storeKey = window.location.pathname;
|
||||||
|
const code = localStorage.getItem(storeKey);
|
||||||
|
if (code) {
|
||||||
|
document.getElementById('code').value = code;
|
||||||
|
await render(code);
|
||||||
|
}
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
startOnLoad: true,
|
startOnLoad: true,
|
||||||
logLevel: 0,
|
logLevel: 0,
|
||||||
});
|
});
|
||||||
const value = `graph TD\nHello --> World`;
|
document.getElementById('code').addEventListener('input', async (e) => {
|
||||||
const el = document.getElementById('dynamicDiagram');
|
const value = e.target.value;
|
||||||
const { svg } = await mermaid.render('dd', value);
|
localStorage.setItem(storeKey, value);
|
||||||
console.log(svg);
|
await render(value);
|
||||||
el.innerHTML = svg;
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="/dev/reload.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
22
demos/dev/reload.js
Normal file
22
demos/dev/reload.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Connect to the server and reload the page if the server sends a reload message
|
||||||
|
const connectToEvents = () => {
|
||||||
|
const events = new EventSource('/events');
|
||||||
|
const loadTime = Date.now();
|
||||||
|
events.onmessage = (event) => {
|
||||||
|
const time = JSON.parse(event.data);
|
||||||
|
if (time && time > loadTime) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
events.onerror = (error) => {
|
||||||
|
console.error(error);
|
||||||
|
events.close();
|
||||||
|
// Try to reconnect after 1 second in case of errors
|
||||||
|
setTimeout(connectToEvents, 1000);
|
||||||
|
};
|
||||||
|
events.onopen = () => {
|
||||||
|
console.log('Connected to live reload server');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
setTimeout(connectToEvents, 500);
|
35
demos/flowchart-elk.html
Normal file
35
demos/flowchart-elk.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>Mermaid Flowchart ELK Test Page</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Flowchart ELK</h1>
|
||||||
|
<pre class="mermaid">
|
||||||
|
flowchart-elk TD
|
||||||
|
A([Start]) ==> B[Step 1]
|
||||||
|
B ==> C{Flow 1}
|
||||||
|
C -- Choice 1.1 --> D[Step 2.1]
|
||||||
|
C -- Choice 1.3 --> I[Step 2.3]
|
||||||
|
C == Choice 1.2 ==> E[Step 2.2]
|
||||||
|
D --> F{Flow 2}
|
||||||
|
E ==> F{Flow 2}
|
||||||
|
F{Flow 2} == Choice 2.1 ==> H[Feedback node]
|
||||||
|
H[Feedback node] ==> B[Step 1]
|
||||||
|
F{Flow 2} == Choice 2.2 ==> G((Finish))
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
import flowchartELK from './mermaid-flowchart-elk.esm.mjs';
|
||||||
|
await mermaid.registerExternalDiagrams([flowchartELK]);
|
||||||
|
mermaid.initialize({
|
||||||
|
logLevel: 3,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -81,6 +81,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<h2><a href="./sankey.html">Sankey</a></h2>
|
<h2><a href="./sankey.html">Sankey</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2><a href="./packet.html">Packet</a></h2>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><a href="./block.html">Layered Blocks</a></h2>
|
<h2><a href="./block.html">Layered Blocks</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
141
demos/packet.html
Normal file
141
demos/packet.html
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
<style>
|
||||||
|
div.mermaid {
|
||||||
|
font-family: 'Courier New', Courier, monospace !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Packet diagram demo</h1>
|
||||||
|
|
||||||
|
<div class="diagrams">
|
||||||
|
<pre class="mermaid">
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
</pre
|
||||||
|
>
|
||||||
|
|
||||||
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
packet:
|
||||||
|
showBits: false
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
</pre
|
||||||
|
>
|
||||||
|
|
||||||
|
<pre class="mermaid">
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
theme: forest
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
title Forest theme
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
</pre
|
||||||
|
>
|
||||||
|
|
||||||
|
<pre class="mermaid" style="background-color: black">
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
theme: dark
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
title Dark theme
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-223: "data"
|
||||||
|
</pre
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
|
mermaid.initialize({
|
||||||
|
logLevel: 3,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.diagrams {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
width: 45vw;
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -50,7 +50,7 @@
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from '/mermaid.esm.mjs';
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
theme: 'forest',
|
theme: 'forest',
|
||||||
logLevel: 3,
|
logLevel: 3,
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
• `Optional` **suppressErrors**: `boolean`
|
• `Optional` **suppressErrors**: `boolean`
|
||||||
|
|
||||||
|
If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
|
||||||
|
The `parseError` function will not be called.
|
||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:60](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L60)
|
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64)
|
||||||
|
21
docs/config/setup/interfaces/mermaidAPI.ParseResult.md
Normal file
21
docs/config/setup/interfaces/mermaidAPI.ParseResult.md
Normal 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/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)
|
@ -14,10 +14,6 @@
|
|||||||
|
|
||||||
• `Optional` **bindFunctions**: (`element`: `Element`) => `void`
|
• `Optional` **bindFunctions**: (`element`: `Element`) => `void`
|
||||||
|
|
||||||
#### Type declaration
|
|
||||||
|
|
||||||
▸ (`element`): `void`
|
|
||||||
|
|
||||||
Bind function to be called after the svg has been inserted into the DOM.
|
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.
|
||||||
|
|
||||||
@ -27,6 +23,10 @@ div.innerHTML = svg;
|
|||||||
bindFunctions?.(div); // To call bindFunctions only if it's present.
|
bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Type declaration
|
||||||
|
|
||||||
|
▸ (`element`): `void`
|
||||||
|
|
||||||
##### Parameters
|
##### Parameters
|
||||||
|
|
||||||
| Name | Type |
|
| Name | Type |
|
||||||
@ -39,7 +39,19 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80)
|
[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### diagramType
|
||||||
|
|
||||||
|
• **diagramType**: `string`
|
||||||
|
|
||||||
|
The diagram type, e.g. 'flowchart', 'sequence', etc.
|
||||||
|
|
||||||
|
#### Defined in
|
||||||
|
|
||||||
|
[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -51,4 +63,4 @@ The svg code for the rendered graph.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:70](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L70)
|
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[defaultConfig.ts:272](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L272)
|
[defaultConfig.ts:275](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L275)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
## Interfaces
|
## Interfaces
|
||||||
|
|
||||||
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
|
- [ParseOptions](../interfaces/mermaidAPI.ParseOptions.md)
|
||||||
|
- [ParseResult](../interfaces/mermaidAPI.ParseResult.md)
|
||||||
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
|
- [RenderResult](../interfaces/mermaidAPI.RenderResult.md)
|
||||||
|
|
||||||
## References
|
## References
|
||||||
@ -25,13 +26,13 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64)
|
[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74)
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
### mermaidAPI
|
### 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)) => `Promise`<`boolean`> ; `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 }>
|
• `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
|
## mermaidAPI configuration defaults
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ mermaid.initialize(config);
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:607](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L607)
|
[mermaidAPI.ts:622](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L622)
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ Return the last node appended
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:263](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L263)
|
[mermaidAPI.ts:277](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L277)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -153,7 +154,7 @@ the cleaned up svgCode
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:209](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L209)
|
[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:139](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L139)
|
[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L186)
|
[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -228,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:124](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L124)
|
[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -254,7 +255,7 @@ Put the svgCode into an iFrame. Return the iFrame code
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:240](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L240)
|
[mermaidAPI.ts:254](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L254)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -279,4 +280,4 @@ Remove any existing elements from the given document
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:313](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L313)
|
[mermaidAPI.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L327)
|
||||||
|
@ -64,7 +64,7 @@ Example:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ Example:
|
|||||||
B-->D(fa:fa-spinner);
|
B-->D(fa:fa-spinner);
|
||||||
</pre>
|
</pre>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -331,15 +331,17 @@ module.exports = (options) ->
|
|||||||
|
|
||||||
## Advanced usage
|
## Advanced usage
|
||||||
|
|
||||||
**Syntax validation without rendering (Work in Progress)**
|
### Syntax validation without rendering
|
||||||
|
|
||||||
The **mermaid.parse(txt)** function validates graph definitions without rendering a graph. **[This function is still a work in progress](https://github.com/mermaid-js/mermaid/issues/1066), find alternatives below.**
|
The `mermaid.parse(text, parseOptions)` function validates graph definitions without rendering a graph.
|
||||||
|
|
||||||
The function **mermaid.parse(txt)**, takes a text string as an argument and returns true if the definition follows mermaid's syntax and
|
The function `mermaid.parse(text, parseOptions)`, takes a text string as an argument and returns `{ diagramType: string }` if the definition follows mermaid's syntax.
|
||||||
false if it does not. The parseError function will be called when the parse function returns false.
|
|
||||||
|
|
||||||
When the parser encounters invalid syntax the **mermaid.parseError** function is called. It is possible to override this
|
If the definition is invalid, the function returns `false` if `parseOptions.suppressErrors` is set to `true`. Otherwise, it throws an error.
|
||||||
function in order to handle the error in an application-specific way.
|
|
||||||
|
The parseError function will be called when the parse function throws an error. It will not be called if `parseOptions.suppressErrors` is set to `true`.
|
||||||
|
|
||||||
|
It is possible to override this function in order to handle the error in an application-specific way.
|
||||||
|
|
||||||
The code-example below in meta code illustrates how this could work:
|
The code-example below in meta code illustrates how this could work:
|
||||||
|
|
||||||
@ -359,26 +361,10 @@ const textFieldUpdated = async function () {
|
|||||||
bindEventHandler('change', 'code', textFieldUpdated);
|
bindEventHandler('change', 'code', textFieldUpdated);
|
||||||
```
|
```
|
||||||
|
|
||||||
**Alternative to mermaid.parse():**
|
|
||||||
One effective and more future-proof method of validating your graph definitions, is to paste and render them via the [Mermaid Live Editor](https://mermaid.live/). This will ensure that your code is compliant with the syntax of Mermaid's most recent version.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Mermaid takes a number of options which lets you tweak the rendering of the diagrams. Currently there are three ways of
|
You can pass the required configuration to the `mermaid.initialize` call. This is the preferred way of configuring mermaid.
|
||||||
setting the options in mermaid.
|
The list of configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
|
||||||
|
|
||||||
1. Instantiation of the configuration using the initialize call
|
|
||||||
2. _Using the global mermaid object_ - **Deprecated**
|
|
||||||
3. _using the global mermaid_config object_ - **Deprecated**
|
|
||||||
4. Instantiation of the configuration using the **mermaid.init** call- **Deprecated**
|
|
||||||
|
|
||||||
The list above has two ways too many of doing this. Three are deprecated and will eventually be removed. The list of
|
|
||||||
configuration objects are described [in the mermaidAPI documentation](./setup/README.md).
|
|
||||||
|
|
||||||
## Using the `mermaidAPI.initialize`/`mermaid.initialize` call
|
|
||||||
|
|
||||||
The future proof way of setting the configuration is by using the initialization call to mermaid or mermaidAPI depending
|
|
||||||
on what kind of integration you use.
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
@ -408,35 +394,6 @@ mermaid.startOnLoad = true;
|
|||||||
> **Warning**
|
> **Warning**
|
||||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
||||||
|
|
||||||
## Using the mermaid_config
|
|
||||||
|
|
||||||
It is possible to set some configuration via the mermaid object. The two parameters that are supported using this
|
|
||||||
approach are:
|
|
||||||
|
|
||||||
- mermaid_config.startOnLoad
|
|
||||||
- mermaid_config.htmlLabels
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
mermaid_config.startOnLoad = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Warning**
|
|
||||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
|
||||||
|
|
||||||
## Using the mermaid.init call
|
|
||||||
|
|
||||||
To set some configuration via the mermaid object. The two parameters that are supported using this approach are:
|
|
||||||
|
|
||||||
- mermaid_config.startOnLoad
|
|
||||||
- mermaid_config.htmlLabels
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
mermaid_config.startOnLoad = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Warning**
|
|
||||||
> This way of setting the configuration is deprecated. Instead the preferred way is to use the initialize method. This functionality is only kept for backwards compatibility.
|
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
cspell:locale en,en-gb
|
cspell:locale en,en-gb
|
||||||
cspell:ignore pumbaa
|
cspell:ignore pumbaa
|
||||||
|
@ -222,7 +222,7 @@ Communication tools and platforms
|
|||||||
| GitHub + Mermaid | - | [🦊🔗](https://addons.mozilla.org/firefox/addon/github-mermaid/) | - | - | [🐙🔗](https://github.com/BackMarket/github-mermaid-extension) |
|
| GitHub + Mermaid | - | [🦊🔗](https://addons.mozilla.org/firefox/addon/github-mermaid/) | - | - | [🐙🔗](https://github.com/BackMarket/github-mermaid-extension) |
|
||||||
| Asciidoctor Live Preview | [🎡🔗](https://chromewebstore.google.com/detail/asciidoctorjs-live-previe/iaalpfgpbocpdfblpnhhgllgbdbchmia) | - | - | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/asciidoctorjs-live-previ/pefkelkanablhjdekgdahplkccnbdggd?hl=en-US) | - |
|
| Asciidoctor Live Preview | [🎡🔗](https://chromewebstore.google.com/detail/asciidoctorjs-live-previe/iaalpfgpbocpdfblpnhhgllgbdbchmia) | - | - | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/asciidoctorjs-live-previ/pefkelkanablhjdekgdahplkccnbdggd?hl=en-US) | - |
|
||||||
| Diagram Tab | - | - | - | - | [🐙🔗](https://github.com/khafast/diagramtab) |
|
| Diagram Tab | - | - | - | - | [🐙🔗](https://github.com/khafast/diagramtab) |
|
||||||
| Markdown Diagrams | [🎡🔗](https://chromewebstore.google.com/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel/) | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/) | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/) | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe) | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
|
| Markdown Diagrams | [🎡🔗](https://chromewebstore.google.com/detail/markdown-diagrams/pmoglnmodacnbbofbgcagndelmgaclel) | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-diagrams/) | [🔴🔗](https://addons.opera.com/en/extensions/details/markdown-diagrams/) | [🌀🔗](https://microsoftedge.microsoft.com/addons/detail/markdown-diagrams/hceenoomhhdkjjijnmlclkpenkapfihe) | [🐙🔗](https://github.com/marcozaccari/markdown-diagrams-browser-extension/tree/master/doc/examples) |
|
||||||
| Markdown Viewer | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | - | - | [🐙🔗](https://github.com/simov/markdown-viewer) |
|
| Markdown Viewer | - | [🦊🔗](https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/) | - | - | [🐙🔗](https://github.com/simov/markdown-viewer) |
|
||||||
| Extensions for Mermaid | - | - | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
| Extensions for Mermaid | - | - | [🔴🔗](https://addons.opera.com/en/extensions/details/extensions-for-mermaid/) | - | [🐙🔗](https://github.com/Stefan-S/mermaid-extension) |
|
||||||
| Chrome Diagrammer | [🎡🔗](https://chromewebstore.google.com/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - |
|
| Chrome Diagrammer | [🎡🔗](https://chromewebstore.google.com/detail/chrome-diagrammer/bkpbgjmkomfoakfklcjeoegkklgjnnpk) | - | - | - | - |
|
||||||
|
@ -224,7 +224,7 @@ b. The importing of the Mermaid library through the `mermaid.esm.mjs` or `mermai
|
|||||||
```html
|
```html
|
||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
mermaid.initialize({ startOnLoad: true });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@ -246,23 +246,23 @@ In this example, the `mermaidAPI` is being called through the `CDN`:
|
|||||||
<body>
|
<body>
|
||||||
Here is one mermaid diagram:
|
Here is one mermaid diagram:
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] --> B[Load Balancer]
|
A[Client] --> B[Load Balancer]
|
||||||
B --> C[Server1]
|
B --> C[Server1]
|
||||||
B --> D[Server2]
|
B --> D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
And here is another:
|
And here is another:
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] -->|tcp_123| B
|
A[Client] -->|tcp_123| B
|
||||||
B(Load Balancer)
|
B(Load Balancer)
|
||||||
B -->|tcp_456| C[Server1]
|
B -->|tcp_456| C[Server1]
|
||||||
B -->|tcp_456| D[Server2]
|
B -->|tcp_456| D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
mermaid.initialize({ startOnLoad: true });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@ -278,15 +278,15 @@ In this example, `mermaid.js` is referenced in `src` as a separate JavaScript fi
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph LR
|
graph LR
|
||||||
A --- B
|
A --- B
|
||||||
B-->C[fa:fa-ban forbidden]
|
B-->C[fa:fa-ban forbidden]
|
||||||
B-->D(fa:fa-spinner);
|
B-->D(fa:fa-spinner);
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
graph TD
|
graph TD
|
||||||
A[Client] --> B[Load Balancer]
|
A[Client] --> B[Load Balancer]
|
||||||
B --> C[Server1]
|
B --> C[Server1]
|
||||||
B --> D[Server2]
|
B --> D[Server2]
|
||||||
</pre>
|
</pre>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
@ -317,7 +317,7 @@ To select a version:
|
|||||||
|
|
||||||
Replace `<version>` with the desired version number.
|
Replace `<version>` with the desired version number.
|
||||||
|
|
||||||
Latest Version: <https://cdn.jsdelivr.net/npm/mermaid@10>
|
Latest Version: <https://cdn.jsdelivr.net/npm/mermaid@11>
|
||||||
|
|
||||||
## Deploying Mermaid
|
## Deploying Mermaid
|
||||||
|
|
||||||
@ -335,7 +335,7 @@ To Deploy Mermaid:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
mermaid.initialize({ startOnLoad: true });
|
mermaid.initialize({ startOnLoad: true });
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
@ -300,7 +300,7 @@ From version 9.4.0 you can simplify this code to:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
141
docs/syntax/packet.md
Normal file
141
docs/syntax/packet.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
> **Warning**
|
||||||
|
>
|
||||||
|
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||||
|
>
|
||||||
|
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/packet.md](../../packages/mermaid/src/docs/syntax/packet.md).
|
||||||
|
|
||||||
|
# Packet Diagram (v\<MERMAID_RELEASE_VERSION>+)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
A packet diagram is a visual representation used to illustrate the structure and contents of a network packet. Network packets are the fundamental units of data transferred over a network.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This diagram type is particularly useful for network engineers, educators, and students who require a clear and concise way to represent the structure of network packets.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
```md
|
||||||
|
packet-beta
|
||||||
|
start: "Block name" %% Single-bit block
|
||||||
|
start-end: "Block name" %% Multi-bit blocks
|
||||||
|
... More Fields ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
---
|
||||||
|
title: "TCP Packet"
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-255: "Data (variable length)"
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
---
|
||||||
|
title: "TCP Packet"
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
64-95: "Acknowledgment Number"
|
||||||
|
96-99: "Data Offset"
|
||||||
|
100-105: "Reserved"
|
||||||
|
106: "URG"
|
||||||
|
107: "ACK"
|
||||||
|
108: "PSH"
|
||||||
|
109: "RST"
|
||||||
|
110: "SYN"
|
||||||
|
111: "FIN"
|
||||||
|
112-127: "Window"
|
||||||
|
128-143: "Checksum"
|
||||||
|
144-159: "Urgent Pointer"
|
||||||
|
160-191: "(Options and Padding)"
|
||||||
|
192-255: "Data (variable length)"
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
packet-beta
|
||||||
|
title UDP Packet
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-47: "Length"
|
||||||
|
48-63: "Checksum"
|
||||||
|
64-95: "Data (variable length)"
|
||||||
|
```
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
packet-beta
|
||||||
|
title UDP Packet
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-47: "Length"
|
||||||
|
48-63: "Checksum"
|
||||||
|
64-95: "Data (variable length)"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Details of Syntax
|
||||||
|
|
||||||
|
- **Ranges**: Each line after the title represents a different field in the packet. The range (e.g., `0-15`) indicates the bit positions in the packet.
|
||||||
|
- **Field Description**: A brief description of what the field represents, enclosed in quotes.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Please refer to the [configuration](/config/schema-docs/config-defs-packet-diagram-config.html) guide for details.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Theme variables are not currently working due to a mermaid bug. The passed values are not being propagated into styles function.
|
||||||
|
|
||||||
|
## Theme Variables
|
||||||
|
|
||||||
|
| Property | Description | Default Value |
|
||||||
|
| ---------------- | -------------------------- | ------------- |
|
||||||
|
| byteFontSize | Font size of the bytes | '10px' |
|
||||||
|
| startByteColor | Color of the starting byte | 'black' |
|
||||||
|
| endByteColor | Color of the ending byte | 'black' |
|
||||||
|
| labelColor | Color of the labels | 'black' |
|
||||||
|
| labelFontSize | Font size of the labels | '12px' |
|
||||||
|
| titleColor | Color of the title | 'black' |
|
||||||
|
| titleFontSize | Font size of the title | '14px' |
|
||||||
|
| blockStrokeColor | Color of the block stroke | 'black' |
|
||||||
|
| blockStrokeWidth | Width of the block stroke | '1' |
|
||||||
|
| blockFillColor | Fill color of the block | '#efefef' |
|
||||||
|
|
||||||
|
## Example on config and theme
|
||||||
|
|
||||||
|
```mermaid-example
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
packet:
|
||||||
|
showBits: true
|
||||||
|
themeVariables:
|
||||||
|
packet:
|
||||||
|
startByteColor: red
|
||||||
|
---
|
||||||
|
packet-beta
|
||||||
|
0-15: "Source Port"
|
||||||
|
16-31: "Destination Port"
|
||||||
|
32-63: "Sequence Number"
|
||||||
|
```
|
||||||
|
|
||||||
|
-->
|
@ -469,7 +469,7 @@ You can use this method to add mermaid including the timeline diagram to a web p
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
base = ""
|
base = ""
|
||||||
|
|
||||||
# Directory that contains the deploy-ready HTML files and
|
# Directory that contains the deploy-ready HTML files and
|
||||||
# assets generated by the build. This is an absolute path relative
|
# assets generated by the build. This is an absolute path relative
|
||||||
# to the base directory, which is the root by default (/).
|
# to the base directory, which is the root by default (/).
|
||||||
# This sample publishes the directory located at the absolute
|
# This sample publishes the directory located at the absolute
|
||||||
# path "root/project/build-output"
|
# path "root/project/build-output"
|
||||||
|
|
||||||
publish = "mermaid-live-editor/docs"
|
publish = "mermaid-live-editor/docs"
|
||||||
|
25
package.json
25
package.json
@ -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.1",
|
"packageManager": "pnpm@8.15.4",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"diagram",
|
"diagram",
|
||||||
"markdown",
|
"markdown",
|
||||||
@ -15,15 +15,15 @@
|
|||||||
"git graph"
|
"git graph"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:vite": "tsx .vite/build.ts",
|
"build": "pnpm build:esbuild && pnpm build:types",
|
||||||
"build:mermaid": "pnpm build:vite --mermaid",
|
"build:esbuild": "pnpm run -r clean && tsx .esbuild/build.ts",
|
||||||
"build:viz": "pnpm build:mermaid --visualize",
|
"build:mermaid": "pnpm build:esbuild --mermaid",
|
||||||
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-zenuml/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-example-diagram/tsconfig.json --emitDeclarationOnly",
|
"build:viz": "pnpm build:esbuild --visualize",
|
||||||
|
"build:types": "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",
|
||||||
"build:watch": "pnpm build:vite --watch",
|
"dev": "tsx .esbuild/server.ts",
|
||||||
"build": "pnpm run -r clean && pnpm build:types && pnpm build:vite",
|
"dev:vite": "tsx .vite/server.ts",
|
||||||
"dev": "concurrently \"pnpm build:vite --watch\" \"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",
|
|
||||||
"release": "pnpm build",
|
"release": "pnpm build",
|
||||||
"lint": "eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
|
"lint": "eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
|
||||||
"lint:fix": "eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts",
|
"lint:fix": "eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts",
|
||||||
@ -32,8 +32,8 @@
|
|||||||
"cypress": "cypress run",
|
"cypress": "cypress run",
|
||||||
"cypress:open": "cypress open",
|
"cypress:open": "cypress open",
|
||||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||||
|
"e2e:coverage": "start-server-and-test dev:coverage http://localhost:9000/ cypress",
|
||||||
"coverage:cypress:clean": "rimraf .nyc_output coverage/cypress",
|
"coverage:cypress:clean": "rimraf .nyc_output coverage/cypress",
|
||||||
"e2e:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm e2e",
|
|
||||||
"coverage:merge": "tsx scripts/coverage.ts",
|
"coverage:merge": "tsx scripts/coverage.ts",
|
||||||
"coverage": "pnpm test:coverage --run && pnpm e2e:coverage && pnpm coverage:merge",
|
"coverage": "pnpm test:coverage --run && pnpm e2e:coverage && pnpm coverage:merge",
|
||||||
"ci": "vitest run",
|
"ci": "vitest run",
|
||||||
@ -74,7 +74,7 @@
|
|||||||
"@types/jsdom": "^21.1.1",
|
"@types/jsdom": "^21.1.1",
|
||||||
"@types/lodash": "^4.14.194",
|
"@types/lodash": "^4.14.194",
|
||||||
"@types/mdast": "^3.0.11",
|
"@types/mdast": "^3.0.11",
|
||||||
"@types/node": "^20.11.10",
|
"@types/node": "^20.11.17",
|
||||||
"@types/prettier": "^2.7.2",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/rollup-plugin-visualizer": "^4.2.1",
|
"@types/rollup-plugin-visualizer": "^4.2.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||||
@ -83,6 +83,7 @@
|
|||||||
"@vitest/spy": "^0.34.0",
|
"@vitest/spy": "^0.34.0",
|
||||||
"@vitest/ui": "^0.34.0",
|
"@vitest/ui": "^0.34.0",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
"concurrently": "^8.0.1",
|
"concurrently": "^8.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cspell": "^8.3.2",
|
"cspell": "^8.3.2",
|
||||||
@ -108,7 +109,9 @@
|
|||||||
"jison": "^0.4.18",
|
"jison": "^0.4.18",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsdom": "^22.0.0",
|
"jsdom": "^22.0.0",
|
||||||
|
"langium-cli": "3.0.1",
|
||||||
"lint-staged": "^13.2.1",
|
"lint-staged": "^13.2.1",
|
||||||
|
"markdown-table": "^3.0.3",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"pnpm": "^8.6.8",
|
"pnpm": "^8.6.8",
|
||||||
|
45
packages/mermaid-flowchart-elk/package.json
Normal file
45
packages/mermaid-flowchart-elk/package.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"name": "@mermaid-js/flowchart-elk",
|
||||||
|
"version": "1.0.0-rc.1",
|
||||||
|
"description": "Flowchart plugin for mermaid with ELK layout",
|
||||||
|
"module": "dist/mermaid-flowchart-elk.core.mjs",
|
||||||
|
"types": "dist/packages/mermaid-flowchart-elk/src/detector.d.ts",
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/mermaid-flowchart-elk.core.mjs",
|
||||||
|
"types": "./dist/packages/mermaid-flowchart-elk/src/detector.d.ts"
|
||||||
|
},
|
||||||
|
"./*": "./*"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"diagram",
|
||||||
|
"markdown",
|
||||||
|
"flowchart",
|
||||||
|
"elk",
|
||||||
|
"mermaid"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prepublishOnly": "pnpm -w run build"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mermaid-js/mermaid"
|
||||||
|
},
|
||||||
|
"author": "Knut Sveidqvist",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"d3": "^7.4.0",
|
||||||
|
"dagre-d3-es": "7.0.10",
|
||||||
|
"khroma": "^2.0.0",
|
||||||
|
"elkjs": "^0.8.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"concurrently": "^8.0.0",
|
||||||
|
"rimraf": "^5.0.0",
|
||||||
|
"mermaid": "workspace:^"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
32
packages/mermaid-flowchart-elk/src/detector.ts
Normal file
32
packages/mermaid-flowchart-elk/src/detector.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import type {
|
||||||
|
ExternalDiagramDefinition,
|
||||||
|
DiagramDetector,
|
||||||
|
DiagramLoader,
|
||||||
|
} from '../../mermaid/src/diagram-api/types.js';
|
||||||
|
|
||||||
|
const id = 'flowchart-elk';
|
||||||
|
|
||||||
|
const detector: DiagramDetector = (txt, config): boolean => {
|
||||||
|
if (
|
||||||
|
// If diagram explicitly states flowchart-elk
|
||||||
|
/^\s*flowchart-elk/.test(txt) ||
|
||||||
|
// If a flowchart/graph diagram has their default renderer set to elk
|
||||||
|
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loader: DiagramLoader = async () => {
|
||||||
|
const { diagram } = await import('./diagram-definition.js');
|
||||||
|
return { id, diagram };
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugin: ExternalDiagramDefinition = {
|
||||||
|
id,
|
||||||
|
detector,
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default plugin;
|
12
packages/mermaid-flowchart-elk/src/diagram-definition.ts
Normal file
12
packages/mermaid-flowchart-elk/src/diagram-definition.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// @ts-ignore: JISON typing missing
|
||||||
|
import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison';
|
||||||
|
import * as db from '../../mermaid/src/diagrams/flowchart/flowDb.js';
|
||||||
|
import styles from '../../mermaid/src/diagrams/flowchart/styles.js';
|
||||||
|
import renderer from './flowRenderer-elk.js';
|
||||||
|
|
||||||
|
export const diagram = {
|
||||||
|
db,
|
||||||
|
renderer,
|
||||||
|
parser,
|
||||||
|
styles,
|
||||||
|
};
|
@ -1,17 +1,17 @@
|
|||||||
import { select, line, curveLinear } from 'd3';
|
import { select, line, curveLinear } from 'd3';
|
||||||
import { insertNode } from '../../../dagre-wrapper/nodes.js';
|
import { insertNode } from '../../mermaid/src/dagre-wrapper/nodes.js';
|
||||||
import insertMarkers from '../../../dagre-wrapper/markers.js';
|
import insertMarkers from '../../mermaid/src/dagre-wrapper/markers.js';
|
||||||
import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';
|
import { insertEdgeLabel } from '../../mermaid/src/dagre-wrapper/edges.js';
|
||||||
import { findCommonAncestor } from './render-utils.js';
|
import { findCommonAncestor } from './render-utils.js';
|
||||||
import { labelHelper } from '../../../dagre-wrapper/shapes/util.js';
|
import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js';
|
||||||
import { getConfig } from '../../../config.js';
|
import { getConfig } from '../../mermaid/src/config.js';
|
||||||
import { log } from '../../../logger.js';
|
import { log } from '../../mermaid/src/logger.js';
|
||||||
import { setupGraphViewbox } from '../../../setupGraphViewbox.js';
|
import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js';
|
||||||
import common from '../../common/common.js';
|
import common from '../../mermaid/src/diagrams/common/common.js';
|
||||||
import { interpolateToCurve, getStylesFromArray } from '../../../utils.js';
|
import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js';
|
||||||
import ELK from 'elkjs/lib/elk.bundled.js';
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
||||||
import { getLineFunctionsWithOffset } from '../../../utils/lineWithOffset.js';
|
import { getLineFunctionsWithOffset } from '../../mermaid/src/utils/lineWithOffset.js';
|
||||||
import { addEdgeMarkers } from '../../../dagre-wrapper/edgeMarker.js';
|
import { addEdgeMarkers } from '../../mermaid/src/dagre-wrapper/edgeMarker.js';
|
||||||
|
|
||||||
const elk = new ELK();
|
const elk = new ELK();
|
||||||
|
|
||||||
@ -594,7 +594,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param diagObj
|
* @param diagObj
|
||||||
* @returns {Record<string, import('../../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
* @returns {Record<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');
|
10
packages/mermaid-flowchart-elk/tsconfig.json
Normal file
10
packages/mermaid-flowchart-elk/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "../..",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"types": ["vitest/importMeta", "vitest/globals"]
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*.ts"],
|
||||||
|
"typeRoots": ["./src/types"]
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
"mermaid"
|
"mermaid"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"clean": "rimraf dist",
|
||||||
"prepublishOnly": "pnpm -w run build"
|
"prepublishOnly": "pnpm -w run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
* This is a dummy parser that satisfies the mermaid API logic.
|
* This is a dummy parser that satisfies the mermaid API logic.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: () => {
|
parse: () => {
|
||||||
// no op
|
// no op
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "10.8.0",
|
"version": "11.0.0-alpha.6",
|
||||||
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "./dist/mermaid.core.mjs",
|
"module": "./dist/mermaid.core.mjs",
|
||||||
@ -60,8 +60,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "^6.0.1",
|
"@braintree/sanitize-url": "^6.0.1",
|
||||||
"@types/d3-scale": "^4.0.3",
|
"@mermaid-js/parser": "workspace:^",
|
||||||
"@types/d3-scale-chromatic": "^3.0.0",
|
|
||||||
"cytoscape": "^3.28.1",
|
"cytoscape": "^3.28.1",
|
||||||
"cytoscape-cose-bilkent": "^4.1.0",
|
"cytoscape-cose-bilkent": "^4.1.0",
|
||||||
"d3": "^7.4.0",
|
"d3": "^7.4.0",
|
||||||
@ -74,11 +73,9 @@
|
|||||||
"khroma": "^2.0.0",
|
"khroma": "^2.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mdast-util-from-markdown": "^1.3.0",
|
"mdast-util-from-markdown": "^1.3.0",
|
||||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
|
||||||
"stylis": "^4.1.3",
|
"stylis": "^4.1.3",
|
||||||
"ts-dedent": "^2.2.0",
|
"ts-dedent": "^2.2.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0"
|
||||||
"web-worker": "^1.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@adobe/jsonschema2md": "^7.1.4",
|
"@adobe/jsonschema2md": "^7.1.4",
|
||||||
@ -86,6 +83,7 @@
|
|||||||
"@types/d3": "^7.4.0",
|
"@types/d3": "^7.4.0",
|
||||||
"@types/d3-sankey": "^0.12.1",
|
"@types/d3-sankey": "^0.12.1",
|
||||||
"@types/d3-scale": "^4.0.3",
|
"@types/d3-scale": "^4.0.3",
|
||||||
|
"@types/d3-scale-chromatic": "^3.0.0",
|
||||||
"@types/d3-selection": "^3.0.5",
|
"@types/d3-selection": "^3.0.5",
|
||||||
"@types/d3-shape": "^3.1.1",
|
"@types/d3-shape": "^3.1.1",
|
||||||
"@types/dompurify": "^3.0.2",
|
"@types/dompurify": "^3.0.2",
|
||||||
|
@ -233,6 +233,23 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround for type duplication when a $ref property has siblings.
|
||||||
|
*
|
||||||
|
* @param json - The input JSON object.
|
||||||
|
*
|
||||||
|
* @see https://github.com/bcherny/json-schema-to-typescript/issues/193
|
||||||
|
*/
|
||||||
|
function removeProp(json: any, name: string) {
|
||||||
|
for (const prop in json) {
|
||||||
|
if (prop === name) {
|
||||||
|
delete json[prop];
|
||||||
|
} else if (typeof json[prop] === 'object') {
|
||||||
|
removeProp(json[prop], name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Main function */
|
/** Main function */
|
||||||
async function main() {
|
async function main() {
|
||||||
if (verifyOnly) {
|
if (verifyOnly) {
|
||||||
@ -243,6 +260,8 @@ async function main() {
|
|||||||
|
|
||||||
const configJsonSchema = await loadJsonSchemaFromYaml();
|
const configJsonSchema = await loadJsonSchemaFromYaml();
|
||||||
|
|
||||||
|
removeProp(configJsonSchema, 'default');
|
||||||
|
|
||||||
validateSchema(configJsonSchema);
|
validateSchema(configJsonSchema);
|
||||||
|
|
||||||
// Generate types from JSON Schema
|
// Generate types from JSON Schema
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import * as configApi from './config.js';
|
import * as configApi from './config.js';
|
||||||
import { log } from './logger.js';
|
|
||||||
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI.js';
|
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI.js';
|
||||||
import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
|
import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
|
||||||
import { UnknownDiagramError } from './errors.js';
|
import { UnknownDiagramError } from './errors.js';
|
||||||
import { encodeEntities } from './utils.js';
|
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';
|
||||||
|
|
||||||
@ -15,48 +13,45 @@ export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?:
|
|||||||
* @privateRemarks This is exported as part of the public mermaidAPI.
|
* @privateRemarks This is exported as part of the public mermaidAPI.
|
||||||
*/
|
*/
|
||||||
export class Diagram {
|
export class Diagram {
|
||||||
type = 'graph';
|
public static async fromText(text: string, metadata: Pick<DiagramMetadata, 'title'> = {}) {
|
||||||
parser: DiagramDefinition['parser'];
|
|
||||||
renderer: DiagramDefinition['renderer'];
|
|
||||||
db: DiagramDefinition['db'];
|
|
||||||
private init?: DiagramDefinition['init'];
|
|
||||||
|
|
||||||
private detectError?: UnknownDiagramError;
|
|
||||||
constructor(public text: string, public metadata: Pick<DiagramMetadata, 'title'> = {}) {
|
|
||||||
this.text = encodeEntities(text);
|
|
||||||
this.text += '\n';
|
|
||||||
const cnf = configApi.getConfig();
|
|
||||||
try {
|
|
||||||
this.type = detectType(text, cnf);
|
|
||||||
} catch (e) {
|
|
||||||
this.type = 'error';
|
|
||||||
this.detectError = e as UnknownDiagramError;
|
|
||||||
}
|
|
||||||
const diagram = getDiagram(this.type);
|
|
||||||
log.debug('Type ' + this.type);
|
|
||||||
// Setup diagram
|
|
||||||
this.db = diagram.db;
|
|
||||||
this.renderer = diagram.renderer;
|
|
||||||
this.parser = diagram.parser;
|
|
||||||
this.parser.parser.yy = this.db;
|
|
||||||
this.init = diagram.init;
|
|
||||||
this.parse();
|
|
||||||
}
|
|
||||||
|
|
||||||
parse() {
|
|
||||||
if (this.detectError) {
|
|
||||||
throw this.detectError;
|
|
||||||
}
|
|
||||||
this.db.clear?.();
|
|
||||||
const config = configApi.getConfig();
|
const config = configApi.getConfig();
|
||||||
this.init?.(config);
|
const type = detectType(text, config);
|
||||||
// This block was added for legacy compatibility. Use frontmatter instead of adding more special cases.
|
text = encodeEntities(text) + '\n';
|
||||||
if (this.metadata.title) {
|
try {
|
||||||
this.db.setDiagramTitle?.(this.metadata.title);
|
getDiagram(type);
|
||||||
|
} catch (e) {
|
||||||
|
const loader = getDiagramLoader(type);
|
||||||
|
if (!loader) {
|
||||||
|
throw new UnknownDiagramError(`Diagram ${type} not found.`);
|
||||||
|
}
|
||||||
|
// Diagram not available, loading it.
|
||||||
|
// new diagram will try getDiagram again and if fails then it is a valid throw
|
||||||
|
const { id, diagram } = await loader();
|
||||||
|
registerDiagram(id, diagram);
|
||||||
}
|
}
|
||||||
this.parser.parse(this.text);
|
const { db, parser, renderer, init } = getDiagram(type);
|
||||||
|
if (parser.parser) {
|
||||||
|
// The parser.parser.yy is only present in JISON parsers. So, we'll only set if required.
|
||||||
|
parser.parser.yy = db;
|
||||||
|
}
|
||||||
|
db.clear?.();
|
||||||
|
init?.(config);
|
||||||
|
// This block was added for legacy compatibility. Use frontmatter instead of adding more special cases.
|
||||||
|
if (metadata.title) {
|
||||||
|
db.setDiagramTitle?.(metadata.title);
|
||||||
|
}
|
||||||
|
await parser.parse(text);
|
||||||
|
return new Diagram(type, text, db, parser, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private constructor(
|
||||||
|
public type: string,
|
||||||
|
public text: string,
|
||||||
|
public db: DiagramDefinition['db'],
|
||||||
|
public parser: DiagramDefinition['parser'],
|
||||||
|
public renderer: DiagramDefinition['renderer']
|
||||||
|
) {}
|
||||||
|
|
||||||
async render(id: string, version: string) {
|
async render(id: string, version: string) {
|
||||||
await this.renderer.draw(this.text, id, version, this);
|
await this.renderer.draw(this.text, id, version, this);
|
||||||
}
|
}
|
||||||
@ -69,34 +64,3 @@ export class Diagram {
|
|||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the text asynchronously and generate a Diagram object asynchronously.
|
|
||||||
* **Warning:** This function may be changed in the future.
|
|
||||||
* @alpha
|
|
||||||
* @param text - The mermaid diagram definition.
|
|
||||||
* @param metadata - Diagram metadata, defined in YAML.
|
|
||||||
* @returns A the Promise of a Diagram object.
|
|
||||||
* @throws {@link UnknownDiagramError} if the diagram type can not be found.
|
|
||||||
* @privateRemarks This is exported as part of the public mermaidAPI.
|
|
||||||
*/
|
|
||||||
export const getDiagramFromText = async (
|
|
||||||
text: string,
|
|
||||||
metadata: Pick<DiagramMetadata, 'title'> = {}
|
|
||||||
): Promise<Diagram> => {
|
|
||||||
const type = detectType(text, configApi.getConfig());
|
|
||||||
try {
|
|
||||||
// Trying to find the diagram
|
|
||||||
getDiagram(type);
|
|
||||||
} catch (error) {
|
|
||||||
const loader = getDiagramLoader(type);
|
|
||||||
if (!loader) {
|
|
||||||
throw new UnknownDiagramError(`Diagram ${type} not found.`);
|
|
||||||
}
|
|
||||||
// Diagram not available, loading it.
|
|
||||||
// new diagram will try getDiagram again and if fails then it is a valid throw
|
|
||||||
const { id, diagram } = await loader();
|
|
||||||
registerDiagram(id, diagram);
|
|
||||||
}
|
|
||||||
return new Diagram(text, metadata);
|
|
||||||
};
|
|
||||||
|
@ -61,7 +61,7 @@ export interface MermaidConfig {
|
|||||||
* You may also use `themeCSS` to override this value.
|
* You may also use `themeCSS` to override this value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
theme?: string | 'default' | 'forest' | 'dark' | 'neutral' | 'null';
|
theme?: 'default' | 'forest' | 'dark' | 'neutral' | 'null';
|
||||||
themeVariables?: any;
|
themeVariables?: any;
|
||||||
themeCSS?: string;
|
themeCSS?: string;
|
||||||
/**
|
/**
|
||||||
@ -87,26 +87,11 @@ export interface MermaidConfig {
|
|||||||
* This option decides the amount of logging to be used by mermaid.
|
* This option decides the amount of logging to be used by mermaid.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
logLevel?:
|
logLevel?: 'trace' | 0 | 'debug' | 1 | 'info' | 2 | 'warn' | 3 | 'error' | 4 | 'fatal' | 5;
|
||||||
| number
|
|
||||||
| string
|
|
||||||
| 0
|
|
||||||
| 2
|
|
||||||
| 1
|
|
||||||
| 'trace'
|
|
||||||
| 'debug'
|
|
||||||
| 'info'
|
|
||||||
| 'warn'
|
|
||||||
| 'error'
|
|
||||||
| 'fatal'
|
|
||||||
| 3
|
|
||||||
| 4
|
|
||||||
| 5
|
|
||||||
| undefined;
|
|
||||||
/**
|
/**
|
||||||
* Level of trust for parsed diagram
|
* Level of trust for parsed diagram
|
||||||
*/
|
*/
|
||||||
securityLevel?: string | 'strict' | 'loose' | 'antiscript' | 'sandbox' | undefined;
|
securityLevel?: 'strict' | 'loose' | 'antiscript' | 'sandbox';
|
||||||
/**
|
/**
|
||||||
* Dictates whether mermaid starts on Page load
|
* Dictates whether mermaid starts on Page load
|
||||||
*/
|
*/
|
||||||
@ -169,19 +154,43 @@ export interface MermaidConfig {
|
|||||||
gitGraph?: GitGraphDiagramConfig;
|
gitGraph?: GitGraphDiagramConfig;
|
||||||
c4?: C4DiagramConfig;
|
c4?: C4DiagramConfig;
|
||||||
sankey?: SankeyDiagramConfig;
|
sankey?: SankeyDiagramConfig;
|
||||||
|
packet?: PacketDiagramConfig;
|
||||||
block?: BlockDiagramConfig;
|
block?: BlockDiagramConfig;
|
||||||
dompurifyConfig?: DOMPurifyConfiguration;
|
dompurifyConfig?: DOMPurifyConfiguration;
|
||||||
wrap?: boolean;
|
wrap?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for block diagrams.
|
* The object containing configurations specific for packet diagrams.
|
||||||
*
|
*
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
* via the `definition` "BlockDiagramConfig".
|
* via the `definition` "PacketDiagramConfig".
|
||||||
*/
|
*/
|
||||||
export interface BlockDiagramConfig extends BaseDiagramConfig {
|
export interface PacketDiagramConfig extends BaseDiagramConfig {
|
||||||
padding?: number;
|
/**
|
||||||
|
* The height of each row in the packet diagram.
|
||||||
|
*/
|
||||||
|
rowHeight?: number;
|
||||||
|
/**
|
||||||
|
* The width of each bit in the packet diagram.
|
||||||
|
*/
|
||||||
|
bitWidth?: number;
|
||||||
|
/**
|
||||||
|
* The number of bits to display per row.
|
||||||
|
*/
|
||||||
|
bitsPerRow?: number;
|
||||||
|
/**
|
||||||
|
* Toggle to display or hide bit numbers.
|
||||||
|
*/
|
||||||
|
showBits?: boolean;
|
||||||
|
/**
|
||||||
|
* The horizontal padding between the blocks in a row.
|
||||||
|
*/
|
||||||
|
paddingX?: number;
|
||||||
|
/**
|
||||||
|
* The vertical padding between the rows.
|
||||||
|
*/
|
||||||
|
paddingY?: number;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
@ -197,6 +206,15 @@ export interface BaseDiagramConfig {
|
|||||||
*/
|
*/
|
||||||
useMaxWidth?: boolean;
|
useMaxWidth?: boolean;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* The object containing configurations specific for block diagrams.
|
||||||
|
*
|
||||||
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
|
* via the `definition` "BlockDiagramConfig".
|
||||||
|
*/
|
||||||
|
export interface BlockDiagramConfig extends BaseDiagramConfig {
|
||||||
|
padding?: number;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for c4 diagrams
|
* The object containing configurations specific for c4 diagrams
|
||||||
*
|
*
|
||||||
@ -807,8 +825,8 @@ export interface XYChartConfig extends BaseDiagramConfig {
|
|||||||
* Should show the chart title
|
* Should show the chart title
|
||||||
*/
|
*/
|
||||||
showTitle?: boolean;
|
showTitle?: boolean;
|
||||||
xAxis?: XYChartAxisConfig1;
|
xAxis?: XYChartAxisConfig;
|
||||||
yAxis?: XYChartAxisConfig2;
|
yAxis?: XYChartAxisConfig;
|
||||||
/**
|
/**
|
||||||
* How to plot will be drawn horizontal or vertical
|
* How to plot will be drawn horizontal or vertical
|
||||||
*/
|
*/
|
||||||
@ -818,104 +836,6 @@ export interface XYChartConfig extends BaseDiagramConfig {
|
|||||||
*/
|
*/
|
||||||
plotReservedSpacePercent?: number;
|
plotReservedSpacePercent?: number;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This object contains configuration for XYChart axis config
|
|
||||||
*/
|
|
||||||
export interface XYChartAxisConfig1 {
|
|
||||||
/**
|
|
||||||
* Should show the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
showLabel?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
labelFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis label (tick text)
|
|
||||||
*/
|
|
||||||
labelPadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis title
|
|
||||||
*/
|
|
||||||
showTitle?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis title
|
|
||||||
*/
|
|
||||||
titleFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis title
|
|
||||||
*/
|
|
||||||
titlePadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis tick lines
|
|
||||||
*/
|
|
||||||
showTick?: boolean;
|
|
||||||
/**
|
|
||||||
* length of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickLength?: number;
|
|
||||||
/**
|
|
||||||
* width of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickWidth?: number;
|
|
||||||
/**
|
|
||||||
* Show line across the axis
|
|
||||||
*/
|
|
||||||
showAxisLine?: boolean;
|
|
||||||
/**
|
|
||||||
* Width of the axis line
|
|
||||||
*/
|
|
||||||
axisLineWidth?: number;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This object contains configuration for XYChart axis config
|
|
||||||
*/
|
|
||||||
export interface XYChartAxisConfig2 {
|
|
||||||
/**
|
|
||||||
* Should show the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
showLabel?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis labels (tick text)
|
|
||||||
*/
|
|
||||||
labelFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis label (tick text)
|
|
||||||
*/
|
|
||||||
labelPadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis title
|
|
||||||
*/
|
|
||||||
showTitle?: boolean;
|
|
||||||
/**
|
|
||||||
* font size of the axis title
|
|
||||||
*/
|
|
||||||
titleFontSize?: number;
|
|
||||||
/**
|
|
||||||
* top and bottom space from axis title
|
|
||||||
*/
|
|
||||||
titlePadding?: number;
|
|
||||||
/**
|
|
||||||
* Should show the axis tick lines
|
|
||||||
*/
|
|
||||||
showTick?: boolean;
|
|
||||||
/**
|
|
||||||
* length of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickLength?: number;
|
|
||||||
/**
|
|
||||||
* width of the axis tick lines
|
|
||||||
*/
|
|
||||||
tickWidth?: number;
|
|
||||||
/**
|
|
||||||
* Show line across the axis
|
|
||||||
*/
|
|
||||||
showAxisLine?: boolean;
|
|
||||||
/**
|
|
||||||
* Width of the axis line
|
|
||||||
*/
|
|
||||||
axisLineWidth?: number;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* The object containing configurations specific for entity relationship diagrams
|
* The object containing configurations specific for entity relationship diagrams
|
||||||
*
|
*
|
||||||
@ -936,7 +856,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Directional bias for layout of entities
|
* Directional bias for layout of entities
|
||||||
*/
|
*/
|
||||||
layoutDirection?: string | 'TB' | 'BT' | 'LR' | 'RL';
|
layoutDirection?: 'TB' | 'BT' | 'LR' | 'RL';
|
||||||
/**
|
/**
|
||||||
* The minimum width of an entity box. Expressed in pixels.
|
* The minimum width of an entity box. Expressed in pixels.
|
||||||
*/
|
*/
|
||||||
@ -1001,7 +921,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
* This interface was referenced by `MermaidConfig`'s JSON-Schema
|
||||||
@ -1025,7 +945,7 @@ export interface ClassDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
nodeSpacing?: number;
|
nodeSpacing?: number;
|
||||||
rankSpacing?: number;
|
rankSpacing?: number;
|
||||||
/**
|
/**
|
||||||
@ -1085,7 +1005,7 @@ export interface JourneyDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Prolongs the edge of the diagram downwards.
|
* Prolongs the edge of the diagram downwards.
|
||||||
*
|
*
|
||||||
@ -1164,7 +1084,7 @@ export interface TimelineDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Prolongs the edge of the diagram downwards.
|
* Prolongs the edge of the diagram downwards.
|
||||||
*
|
*
|
||||||
@ -1275,7 +1195,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Controls the display mode.
|
* Controls the display mode.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
displayMode?: string | 'compact';
|
displayMode?: '' | 'compact';
|
||||||
/**
|
/**
|
||||||
* On which day a week-based interval should start
|
* On which day a week-based interval should start
|
||||||
*
|
*
|
||||||
@ -1334,7 +1254,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* Multiline message alignment
|
* Multiline message alignment
|
||||||
*/
|
*/
|
||||||
messageAlign?: string | 'left' | 'center' | 'right';
|
messageAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* Mirror actors under diagram
|
* Mirror actors under diagram
|
||||||
*
|
*
|
||||||
@ -1391,7 +1311,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
|||||||
/**
|
/**
|
||||||
* This sets the text alignment of actor-attached notes
|
* This sets the text alignment of actor-attached notes
|
||||||
*/
|
*/
|
||||||
noteAlign?: string | 'left' | 'center' | 'right';
|
noteAlign?: 'left' | 'center' | 'right';
|
||||||
/**
|
/**
|
||||||
* This sets the font size of actor messages
|
* This sets the font size of actor messages
|
||||||
*/
|
*/
|
||||||
@ -1475,7 +1395,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Defines how mermaid renders curves for flowcharts.
|
* Defines how mermaid renders curves for flowcharts.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
curve?: string | 'basis' | 'linear' | 'cardinal';
|
curve?: 'basis' | 'linear' | 'cardinal';
|
||||||
/**
|
/**
|
||||||
* Represents the padding between the labels and the shape
|
* Represents the padding between the labels and the shape
|
||||||
*
|
*
|
||||||
@ -1487,7 +1407,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
|||||||
* Decides which rendering engine that is to be used for the rendering.
|
* Decides which rendering engine that is to be used for the rendering.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
defaultRenderer?: 'dagre-d3' | 'dagre-wrapper' | 'elk';
|
||||||
/**
|
/**
|
||||||
* Width of nodes where text is wrapped.
|
* Width of nodes where text is wrapped.
|
||||||
*
|
*
|
||||||
@ -1511,13 +1431,7 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
linkColor?: SankeyLinkColor | string;
|
linkColor?: SankeyLinkColor | string;
|
||||||
/**
|
nodeAlignment?: SankeyNodeAlignment;
|
||||||
* Controls the alignment of the Sankey diagrams.
|
|
||||||
*
|
|
||||||
* See <https://github.com/d3/d3-sankey#alignments>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
nodeAlignment?: 'left' | 'right' | 'center' | 'justify';
|
|
||||||
useMaxWidth?: boolean;
|
useMaxWidth?: boolean;
|
||||||
/**
|
/**
|
||||||
* Toggle to display or hide values along with title.
|
* Toggle to display or hide values along with title.
|
||||||
|
@ -257,6 +257,9 @@ const config: RequiredDeep<MermaidConfig> = {
|
|||||||
// TODO: can we make this default to `true` instead?
|
// TODO: can we make this default to `true` instead?
|
||||||
useMaxWidth: false,
|
useMaxWidth: false,
|
||||||
},
|
},
|
||||||
|
packet: {
|
||||||
|
...defaultConfigJson.packet,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyify = (obj: any, prefix = ''): string[] =>
|
const keyify = (obj: any, prefix = ''): string[] =>
|
||||||
|
@ -71,10 +71,9 @@ export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinitio
|
|||||||
|
|
||||||
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
||||||
if (detectors[key]) {
|
if (detectors[key]) {
|
||||||
log.error(`Detector with key ${key} already exists`);
|
log.warn(`Detector with key ${key} already exists. Overwriting.`);
|
||||||
} else {
|
|
||||||
detectors[key] = { detector, loader };
|
|
||||||
}
|
}
|
||||||
|
detectors[key] = { detector, loader };
|
||||||
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import flowchartElk from '../diagrams/flowchart/elk/detector.js';
|
|||||||
import timeline from '../diagrams/timeline/detector.js';
|
import timeline from '../diagrams/timeline/detector.js';
|
||||||
import mindmap from '../diagrams/mindmap/detector.js';
|
import mindmap from '../diagrams/mindmap/detector.js';
|
||||||
import sankey from '../diagrams/sankey/sankeyDetector.js';
|
import sankey from '../diagrams/sankey/sankeyDetector.js';
|
||||||
|
import { packet } from '../diagrams/packet/detector.js';
|
||||||
import block from '../diagrams/block/blockDetector.js';
|
import block from '../diagrams/block/blockDetector.js';
|
||||||
import { registerLazyLoadedDiagrams } from './detectType.js';
|
import { registerLazyLoadedDiagrams } from './detectType.js';
|
||||||
import { registerDiagram } from './diagramAPI.js';
|
import { registerDiagram } from './diagramAPI.js';
|
||||||
@ -51,7 +52,6 @@ export const addDiagrams = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parser: {
|
parser: {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: () => {
|
parse: () => {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Diagrams beginning with --- are not valid. ' +
|
'Diagrams beginning with --- are not valid. ' +
|
||||||
@ -88,6 +88,7 @@ export const addDiagrams = () => {
|
|||||||
journey,
|
journey,
|
||||||
quadrantChart,
|
quadrantChart,
|
||||||
sankey,
|
sankey,
|
||||||
|
packet,
|
||||||
xychart,
|
xychart,
|
||||||
block
|
block
|
||||||
);
|
);
|
||||||
|
@ -2,12 +2,12 @@ import { detectType } from './detectType.js';
|
|||||||
import { getDiagram, registerDiagram } from './diagramAPI.js';
|
import { getDiagram, registerDiagram } from './diagramAPI.js';
|
||||||
import { addDiagrams } from './diagram-orchestration.js';
|
import { addDiagrams } from './diagram-orchestration.js';
|
||||||
import type { DiagramDetector } from './types.js';
|
import type { DiagramDetector } from './types.js';
|
||||||
import { getDiagramFromText } from '../Diagram.js';
|
import { Diagram } from '../Diagram.js';
|
||||||
import { it, describe, expect, beforeAll } from 'vitest';
|
import { it, describe, expect, beforeAll } from 'vitest';
|
||||||
|
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await getDiagramFromText('sequenceDiagram');
|
await Diagram.fromText('sequenceDiagram');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DiagramAPI', () => {
|
describe('DiagramAPI', () => {
|
||||||
@ -39,7 +39,6 @@ describe('DiagramAPI', () => {
|
|||||||
parse: (_text) => {
|
parse: (_text) => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
parser: { yy: {} },
|
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
draw: () => {
|
draw: () => {
|
||||||
|
@ -49,7 +49,7 @@ export const registerDiagram = (
|
|||||||
detector?: DiagramDetector
|
detector?: DiagramDetector
|
||||||
) => {
|
) => {
|
||||||
if (diagrams[id]) {
|
if (diagrams[id]) {
|
||||||
throw new Error(`Diagram ${id} already registered.`);
|
log.warn(`Diagram with id ${id} already registered. Overwriting.`);
|
||||||
}
|
}
|
||||||
diagrams[id] = diagram;
|
diagrams[id] = diagram;
|
||||||
if (detector) {
|
if (detector) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { MermaidConfig } from '../config.type.js';
|
import type { GanttDiagramConfig, MermaidConfig } from '../config.type.js';
|
||||||
import { frontMatterRegex } from './regexes.js';
|
import { frontMatterRegex } from './regexes.js';
|
||||||
// The "* as yaml" part is necessary for tree-shaking
|
// The "* as yaml" part is necessary for tree-shaking
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
@ -6,7 +6,7 @@ import * as yaml from 'js-yaml';
|
|||||||
interface FrontMatterMetadata {
|
interface FrontMatterMetadata {
|
||||||
title?: string;
|
title?: string;
|
||||||
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
||||||
displayMode?: string;
|
displayMode?: GanttDiagramConfig['displayMode'];
|
||||||
config?: MermaidConfig;
|
config?: MermaidConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ export function extractFrontMatter(text: string): FrontMatterResult {
|
|||||||
|
|
||||||
// Only add properties that are explicitly supported, if they exist
|
// Only add properties that are explicitly supported, if they exist
|
||||||
if (parsed.displayMode) {
|
if (parsed.displayMode) {
|
||||||
metadata.displayMode = parsed.displayMode.toString();
|
metadata.displayMode = parsed.displayMode.toString() as GanttDiagramConfig['displayMode'];
|
||||||
}
|
}
|
||||||
if (parsed.title) {
|
if (parsed.title) {
|
||||||
metadata.title = parsed.title.toString();
|
metadata.title = parsed.title.toString();
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import type * as d3 from 'd3';
|
||||||
|
import type { SetRequired } from 'type-fest';
|
||||||
import type { Diagram } from '../Diagram.js';
|
import type { Diagram } from '../Diagram.js';
|
||||||
import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js';
|
import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js';
|
||||||
import type * as d3 from 'd3';
|
|
||||||
|
|
||||||
export interface DiagramMetadata {
|
export interface DiagramMetadata {
|
||||||
title?: string;
|
title?: string;
|
||||||
@ -39,6 +40,22 @@ export interface DiagramDB {
|
|||||||
bindFunctions?: (element: Element) => void;
|
bindFunctions?: (element: Element) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DiagramDB with fields that is required for all new diagrams.
|
||||||
|
*/
|
||||||
|
export type DiagramDBBase<T extends BaseDiagramConfig> = {
|
||||||
|
getConfig: () => Required<T>;
|
||||||
|
} & SetRequired<
|
||||||
|
DiagramDB,
|
||||||
|
| 'clear'
|
||||||
|
| 'getAccTitle'
|
||||||
|
| 'getDiagramTitle'
|
||||||
|
| 'getAccDescription'
|
||||||
|
| 'setAccDescription'
|
||||||
|
| 'setAccTitle'
|
||||||
|
| 'setDiagramTitle'
|
||||||
|
>;
|
||||||
|
|
||||||
// This is what is returned from getClasses(...) methods.
|
// This is what is returned from getClasses(...) methods.
|
||||||
// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word.
|
// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word.
|
||||||
// It makes it clear we're working with a style class definition, even though defining the type is currently difficult.
|
// It makes it clear we're working with a style class definition, even though defining the type is currently difficult.
|
||||||
@ -104,8 +121,8 @@ export type DrawDefinition = (
|
|||||||
) => void | Promise<void>;
|
) => void | Promise<void>;
|
||||||
|
|
||||||
export interface ParserDefinition {
|
export interface ParserDefinition {
|
||||||
parse: (text: string) => void;
|
parse: (text: string) => void | Promise<void>;
|
||||||
parser: { yy: DiagramDB };
|
parser?: { yy: DiagramDB };
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HTML = d3.Selection<HTMLIFrameElement, unknown, Element | null, unknown>;
|
export type HTML = d3.Selection<HTMLIFrameElement, unknown, Element | null, unknown>;
|
||||||
|
@ -1,16 +1,39 @@
|
|||||||
import { describe, test, expect } from 'vitest';
|
import { describe, test, expect } from 'vitest';
|
||||||
import { Diagram, getDiagramFromText } from './Diagram.js';
|
import { Diagram } from './Diagram.js';
|
||||||
import { addDetector } from './diagram-api/detectType.js';
|
import { addDetector } from './diagram-api/detectType.js';
|
||||||
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
||||||
|
import type { DiagramLoader } from './diagram-api/types.js';
|
||||||
|
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
|
||||||
|
const getDummyDiagram = (id: string, title?: string): Awaited<ReturnType<DiagramLoader>> => {
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
diagram: {
|
||||||
|
db: {
|
||||||
|
getDiagramTitle: () => title ?? id,
|
||||||
|
},
|
||||||
|
parser: {
|
||||||
|
parse: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
|
styles: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
describe('diagram detection', () => {
|
describe('diagram detection', () => {
|
||||||
test('should detect inbuilt diagrams', async () => {
|
test('should detect inbuilt diagrams', async () => {
|
||||||
const graph = (await getDiagramFromText('graph TD; A-->B')) as Diagram;
|
const graph = (await Diagram.fromText('graph TD; A-->B')) as Diagram;
|
||||||
expect(graph).toBeInstanceOf(Diagram);
|
expect(graph).toBeInstanceOf(Diagram);
|
||||||
expect(graph.type).toBe('flowchart-v2');
|
expect(graph.type).toBe('flowchart-v2');
|
||||||
const sequence = (await getDiagramFromText(
|
const sequence = (await Diagram.fromText(
|
||||||
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
||||||
)) as Diagram;
|
)) as Diagram;
|
||||||
expect(sequence).toBeInstanceOf(Diagram);
|
expect(sequence).toBeInstanceOf(Diagram);
|
||||||
@ -21,41 +44,33 @@ describe('diagram detection', () => {
|
|||||||
addDetector(
|
addDetector(
|
||||||
'loki',
|
'loki',
|
||||||
(str) => str.startsWith('loki'),
|
(str) => str.startsWith('loki'),
|
||||||
() =>
|
() => Promise.resolve(getDummyDiagram('loki'))
|
||||||
Promise.resolve({
|
|
||||||
id: 'loki',
|
|
||||||
diagram: {
|
|
||||||
db: {},
|
|
||||||
parser: {
|
|
||||||
parse: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
parser: {
|
|
||||||
yy: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
renderer: {
|
|
||||||
draw: () => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
},
|
|
||||||
styles: {},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
const diagram = (await getDiagramFromText('loki TD; A-->B')) as Diagram;
|
const diagram = await Diagram.fromText('loki TD; A-->B');
|
||||||
expect(diagram).toBeInstanceOf(Diagram);
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
expect(diagram.type).toBe('loki');
|
expect(diagram.type).toBe('loki');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should allow external diagrams to override internal ones with same ID', async () => {
|
||||||
|
const title = 'overridden';
|
||||||
|
addDetector(
|
||||||
|
'flowchart-elk',
|
||||||
|
(str) => str.startsWith('flowchart-elk'),
|
||||||
|
() => Promise.resolve(getDummyDiagram('flowchart-elk', title))
|
||||||
|
);
|
||||||
|
const diagram = await Diagram.fromText('flowchart-elk TD; A-->B');
|
||||||
|
expect(diagram).toBeInstanceOf(Diagram);
|
||||||
|
expect(diagram.db.getDiagramTitle?.()).toBe(title);
|
||||||
|
});
|
||||||
|
|
||||||
test('should throw the right error for incorrect diagram', async () => {
|
test('should throw the right error for incorrect diagram', async () => {
|
||||||
await expect(getDiagramFromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
await expect(Diagram.fromText('graph TD; A-->')).rejects.toThrowErrorMatchingInlineSnapshot(`
|
||||||
"Parse error on line 2:
|
"Parse error on line 2:
|
||||||
graph TD; A-->
|
graph TD; A-->
|
||||||
--------------^
|
--------------^
|
||||||
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"
|
Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"
|
||||||
`);
|
`);
|
||||||
await expect(getDiagramFromText('sequenceDiagram; A-->B')).rejects
|
await expect(Diagram.fromText('sequenceDiagram; A-->B')).rejects
|
||||||
.toThrowErrorMatchingInlineSnapshot(`
|
.toThrowErrorMatchingInlineSnapshot(`
|
||||||
"Parse error on line 1:
|
"Parse error on line 1:
|
||||||
...quenceDiagram; A-->B
|
...quenceDiagram; A-->B
|
||||||
@ -65,13 +80,13 @@ Expecting 'TXT', got 'NEWLINE'"
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should throw the right error for unregistered diagrams', async () => {
|
test('should throw the right error for unregistered diagrams', async () => {
|
||||||
await expect(getDiagramFromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
|
await expect(Diagram.fromText('thor TD; A-->B')).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
|
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should consider entity codes when present in diagram defination', async () => {
|
test('should consider entity codes when present in diagram defination', async () => {
|
||||||
const diagram = await getDiagramFromText(`sequenceDiagram
|
const diagram = await Diagram.fromText(`sequenceDiagram
|
||||||
A->>B: I #9829; you!
|
A->>B: I #9829; you!
|
||||||
B->>A: I #9829; you #infin; times more!`);
|
B->>A: I #9829; you #infin; times more!`);
|
||||||
// @ts-ignore: we need to add types for sequenceDb which will be done in separate PR
|
// @ts-ignore: we need to add types for sequenceDb which will be done in separate PR
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
|
||||||
import type { BlockConfig, BlockType, Block, ClassDef } from './blockTypes.js';
|
|
||||||
import * as configApi from '../../config.js';
|
|
||||||
import { clear as commonClear } from '../common/commonDb.js';
|
|
||||||
import { log } from '../../logger.js';
|
|
||||||
import clone from 'lodash-es/clone.js';
|
import clone from 'lodash-es/clone.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
|
import { log } from '../../logger.js';
|
||||||
|
import { clear as commonClear } from '../common/commonDb.js';
|
||||||
|
import type { Block, ClassDef } from './blockTypes.js';
|
||||||
|
|
||||||
// Initialize the node database for simple lookups
|
// Initialize the node database for simple lookups
|
||||||
let blockDatabase: Record<string, Block> = {};
|
let blockDatabase: Record<string, Block> = {};
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
import type { Diagram } from '../../Diagram.js';
|
|
||||||
import * as configApi from '../../config.js';
|
|
||||||
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
|
|
||||||
import { layout } from './layout.js';
|
|
||||||
import type { MermaidConfig, BaseDiagramConfig } from '../../config.type.js';
|
|
||||||
import insertMarkers from '../../dagre-wrapper/markers.js';
|
|
||||||
import {
|
import {
|
||||||
select as d3select,
|
|
||||||
scaleOrdinal as d3scaleOrdinal,
|
scaleOrdinal as d3scaleOrdinal,
|
||||||
schemeTableau10 as d3schemeTableau10,
|
schemeTableau10 as d3schemeTableau10,
|
||||||
|
select as d3select,
|
||||||
} from 'd3';
|
} from 'd3';
|
||||||
import type { ContainerElement } from 'd3';
|
import type { Diagram } from '../../Diagram.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import type { MermaidConfig } from '../../config.type.js';
|
||||||
|
import insertMarkers from '../../dagre-wrapper/markers.js';
|
||||||
import { log } from '../../logger.js';
|
import { log } from '../../logger.js';
|
||||||
import type { BlockDB } from './blockDB.js';
|
|
||||||
import type { Block } from './blockTypes.js';
|
|
||||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||||
|
import type { BlockDB } from './blockDB.js';
|
||||||
|
import { layout } from './layout.js';
|
||||||
|
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the all the styles from classDef statements in the graph definition.
|
* Returns the all the styles from classDef statements in the graph definition.
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
import { getStylesFromArray } from '../../utils.js';
|
|
||||||
import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
|
|
||||||
import { insertEdge, insertEdgeLabel, positionEdgeLabel } from '../../dagre-wrapper/edges.js';
|
|
||||||
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
|
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
|
||||||
import { getConfig } from '../../config.js';
|
import { getConfig } from '../../config.js';
|
||||||
import type { ContainerElement } from 'd3';
|
import { insertEdge, insertEdgeLabel, positionEdgeLabel } from '../../dagre-wrapper/edges.js';
|
||||||
import type { Block } from './blockTypes.js';
|
import { insertNode, positionNode } from '../../dagre-wrapper/nodes.js';
|
||||||
|
import { getStylesFromArray } from '../../utils.js';
|
||||||
import type { BlockDB } from './blockDB.js';
|
import type { BlockDB } from './blockDB.js';
|
||||||
|
import type { Block } from './blockTypes.js';
|
||||||
interface Node {
|
|
||||||
classes: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
||||||
const vertex = block;
|
const vertex = block;
|
||||||
|
14
packages/mermaid/src/diagrams/common/populateCommonDb.ts
Normal file
14
packages/mermaid/src/diagrams/common/populateCommonDb.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { DiagramAST } from '@mermaid-js/parser';
|
||||||
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
|
|
||||||
|
export function populateCommonDb(ast: DiagramAST, db: DiagramDB) {
|
||||||
|
if (ast.accDescr) {
|
||||||
|
db.setAccDescription?.(ast.accDescr);
|
||||||
|
}
|
||||||
|
if (ast.accTitle) {
|
||||||
|
db.setAccTitle?.(ast.accTitle);
|
||||||
|
}
|
||||||
|
if (ast.title) {
|
||||||
|
db.setDiagramTitle?.(ast.title);
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ const diagram: DiagramDefinition = {
|
|||||||
db: {},
|
db: {},
|
||||||
renderer,
|
renderer,
|
||||||
parser: {
|
parser: {
|
||||||
parser: { yy: {} },
|
|
||||||
parse: (): void => {
|
parse: (): void => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import type {
|
|||||||
DiagramDetector,
|
DiagramDetector,
|
||||||
DiagramLoader,
|
DiagramLoader,
|
||||||
} from '../../../diagram-api/types.js';
|
} from '../../../diagram-api/types.js';
|
||||||
|
import { log } from '../../../logger.js';
|
||||||
|
|
||||||
const id = 'flowchart-elk';
|
const id = 'flowchart-elk';
|
||||||
|
|
||||||
@ -13,13 +14,21 @@ const detector: DiagramDetector = (txt, config): boolean => {
|
|||||||
// 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')
|
||||||
) {
|
) {
|
||||||
|
// This will log at the end, hopefully.
|
||||||
|
setTimeout(
|
||||||
|
() =>
|
||||||
|
log.warn(
|
||||||
|
'flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](link) for more details. This diagram will be rendered using `dagre` layout as a fallback.'
|
||||||
|
),
|
||||||
|
500
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const loader: DiagramLoader = async () => {
|
const loader: DiagramLoader = async () => {
|
||||||
const { diagram } = await import('./flowchart-elk-definition.js');
|
const { diagram } = await import('../flowDiagram-v2.js');
|
||||||
return { id, diagram };
|
return { id, diagram };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
// @ts-ignore: JISON typing missing
|
|
||||||
import parser from '../parser/flow.jison';
|
|
||||||
|
|
||||||
import * as db from '../flowDb.js';
|
|
||||||
import renderer from './flowRenderer-elk.js';
|
|
||||||
import styles from './styles.js';
|
|
||||||
|
|
||||||
export const diagram = {
|
|
||||||
db,
|
|
||||||
renderer,
|
|
||||||
parser,
|
|
||||||
styles,
|
|
||||||
};
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user