mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 02:44:17 +01:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			v10.4.0
			...
			sidv/liveR
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5e210753b7 | ||
|   | 350aaf9b51 | ||
|   | 5cd792f027 | 
							
								
								
									
										20
									
								
								.build/common.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.build/common.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | /** | ||||||
|  |  * Shared common options for both ESBuild and Vite | ||||||
|  |  */ | ||||||
|  | export 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', | ||||||
|  |   }, | ||||||
|  | } as const; | ||||||
							
								
								
									
										122
									
								
								.build/jsonSchema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								.build/jsonSchema.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | |||||||
|  | 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', | ||||||
|  |   'requirement', | ||||||
|  |   'mindmap', | ||||||
|  |   'timeline', | ||||||
|  |   'gitGraph', | ||||||
|  |   'c4', | ||||||
|  |   'sankey', | ||||||
|  | ] 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. | ||||||
|  |  */ | ||||||
|  | export 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)};`; | ||||||
|  | }; | ||||||
							
								
								
									
										34
									
								
								.esbuild/build.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.esbuild/build.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | import { build } from 'esbuild'; | ||||||
|  | import { mkdir, writeFile } from 'node:fs/promises'; | ||||||
|  | import { getBuildConfig } from './util.js'; | ||||||
|  | import { packageOptions } from '../.build/common.js'; | ||||||
|  |  | ||||||
|  | const shouldVisualize = process.argv.includes('--visualize'); | ||||||
|  |  | ||||||
|  | const buildPackage = async (entryName: keyof typeof packageOptions) => { | ||||||
|  |   await build(getBuildConfig({ entryName, minify: false })); | ||||||
|  |   const { metafile } = await build( | ||||||
|  |     getBuildConfig({ entryName, minify: true, metafile: shouldVisualize }) | ||||||
|  |   ); | ||||||
|  |   if (metafile) { | ||||||
|  |     // Upload metafile into https://esbuild.github.io/analyze/ | ||||||
|  |     await writeFile(`stats/meta-${entryName}.json`, JSON.stringify(metafile)); | ||||||
|  |   } | ||||||
|  |   await build(getBuildConfig({ entryName, minify: false, core: true })); | ||||||
|  |   await build(getBuildConfig({ entryName, minify: true, format: 'iife' })); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const handler = (e) => { | ||||||
|  |   console.error(e); | ||||||
|  |   process.exit(1); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const main = async () => { | ||||||
|  |   await mkdir('stats').catch(() => {}); | ||||||
|  |   const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; | ||||||
|  |   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; | ||||||
							
								
								
									
										93
									
								
								.esbuild/server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								.esbuild/server.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | import express from 'express'; | ||||||
|  | import type { NextFunction, Request, Response } from 'express'; | ||||||
|  | import cors from 'cors'; | ||||||
|  | import { getBuildConfig } from './util.js'; | ||||||
|  | import { context } from 'esbuild'; | ||||||
|  | import chokidar from 'chokidar'; | ||||||
|  |  | ||||||
|  | const mermaidCtx = await context( | ||||||
|  |   getBuildConfig({ minify: false, core: false, entryName: 'mermaid' }) | ||||||
|  | ); | ||||||
|  | const mermaidIIFECtx = await context( | ||||||
|  |   getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' }) | ||||||
|  | ); | ||||||
|  | const externalCtx = await context( | ||||||
|  |   getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' }) | ||||||
|  | ); | ||||||
|  | const zenumlCtx = await context( | ||||||
|  |   getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' }) | ||||||
|  | ); | ||||||
|  | const contexts = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx]; | ||||||
|  |  | ||||||
|  | const rebuildAll = async () => { | ||||||
|  |   await Promise.all(contexts.map((ctx) => ctx.rebuild())); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | 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() { | ||||||
|  |   const app = express(); | ||||||
|  |   chokidar | ||||||
|  |     .watch('**/src/**/*.{js,ts,yaml,json}', { | ||||||
|  |       ignoreInitial: true, | ||||||
|  |       ignored: [/node_modules/, /dist/, /docs/, /coverage/], | ||||||
|  |     }) | ||||||
|  |     .on('all', async (event, path) => { | ||||||
|  |       // Ignore other events. | ||||||
|  |       if (!['add', 'change'].includes(event)) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       console.log(`${path} changed. Rebuilding...`); | ||||||
|  |       handleFileChange(); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |   app.use(cors()); | ||||||
|  |   app.get('/events', eventsHandler); | ||||||
|  |   app.use(express.static('./packages/mermaid/dist')); | ||||||
|  |   app.use(express.static('./packages/mermaid-zenuml/dist')); | ||||||
|  |   app.use(express.static('./packages/mermaid-example-diagram/dist')); | ||||||
|  |   app.use(express.static('demos')); | ||||||
|  |   app.use(express.static('cypress/platform')); | ||||||
|  |  | ||||||
|  |   app.listen(9000, () => { | ||||||
|  |     console.log(`Listening on http://localhost:9000`); | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | createServer(); | ||||||
							
								
								
									
										81
									
								
								.esbuild/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								.esbuild/util.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | 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)); | ||||||
|  |  | ||||||
|  | interface MermaidBuildOptions { | ||||||
|  |   minify: boolean; | ||||||
|  |   core?: boolean; | ||||||
|  |   metafile?: boolean; | ||||||
|  |   format?: 'esm' | 'iife'; | ||||||
|  |   entryName: keyof typeof packageOptions; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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, | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getBuildConfig = ({ | ||||||
|  |   minify, | ||||||
|  |   core, | ||||||
|  |   entryName, | ||||||
|  |   metafile, | ||||||
|  |   format, | ||||||
|  | }: MermaidBuildOptions): BuildOptions => { | ||||||
|  |   const external: string[] = ['require', 'fs', 'path']; | ||||||
|  |   const { name, file, packageName } = packageOptions[entryName]; | ||||||
|  |   let output: BuildOptions = buildOptions({ | ||||||
|  |     absWorkingDir: resolve(__dirname, `../packages/${packageName}`), | ||||||
|  |     entryPoints: { | ||||||
|  |       [`${name}${core ? '.core' : format === 'iife' ? '' : '.esm'}${ | ||||||
|  |         minify ? '.min' : '' | ||||||
|  |       }`]: `src/${file}`, | ||||||
|  |     }, | ||||||
|  |     metafile, | ||||||
|  |     logLevel: 'info', | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   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'; | ||||||
|  |     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; | ||||||
|  | }; | ||||||
| @@ -3,11 +3,11 @@ 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'; | ||||||
|  |  | ||||||
| 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 +36,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 +54,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: { | ||||||
| @@ -146,8 +102,6 @@ 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 () => { | ||||||
|   | |||||||
| @@ -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,108 +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', |  | ||||||
|   'requirement', |  | ||||||
|   'mindmap', |  | ||||||
|   'timeline', |  | ||||||
|   'gitGraph', |  | ||||||
|   'c4', |  | ||||||
|   'sankey', |  | ||||||
| ] 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. | ||||||
| @@ -119,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 |  | ||||||
|         }; |  | ||||||
|       } |  | ||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -80,6 +80,7 @@ | |||||||
|     "mdbook", |     "mdbook", | ||||||
|     "mermaidjs", |     "mermaidjs", | ||||||
|     "mermerd", |     "mermerd", | ||||||
|  |     "metafile", | ||||||
|     "mindaugas", |     "mindaugas", | ||||||
|     "mindmap", |     "mindmap", | ||||||
|     "mindmaps", |     "mindmaps", | ||||||
|   | |||||||
							
								
								
									
										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>'); |  | ||||||
|   }); |  | ||||||
| }); |  | ||||||
| @@ -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]); | ||||||
|   | |||||||
							
								
								
									
										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> | ||||||
|   | |||||||
| @@ -30,5 +30,33 @@ graph TB | |||||||
|       console.log(svg); |       console.log(svg); | ||||||
|       el.innerHTML = svg; |       el.innerHTML = svg; | ||||||
|     </script> |     </script> | ||||||
|  |  | ||||||
|  |     <script> | ||||||
|  |       // Set to false to disable live reload | ||||||
|  |       const liveReload = true; | ||||||
|  |       // 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'); | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |       if (liveReload) { | ||||||
|  |         connectToEvents(); | ||||||
|  |       } | ||||||
|  |     </script> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|   | |||||||
| @@ -38,7 +38,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', | ||||||
|         // themeCSS: '.node rect { fill: red; }', |         // themeCSS: '.node rect { fill: red; }', | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -285,7 +285,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 | ||||||
|  |  | ||||||
| @@ -303,7 +303,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> | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -128,7 +128,7 @@ b. The importing of mermaid library through the `mermaid.esm.mjs` or `mermaid.es | |||||||
| ```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> | ||||||
| @@ -168,7 +168,7 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. However, doi | |||||||
|     </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> | ||||||
|   | |||||||
| @@ -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> | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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> | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								package.json
									
									
									
									
									
								
							| @@ -15,14 +15,14 @@ | |||||||
|     "git graph" |     "git graph" | ||||||
|   ], |   ], | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "build:vite": "ts-node-esm --transpileOnly .vite/build.ts", |     "build": "pnpm run -r clean && pnpm build:esbuild && pnpm build:types", | ||||||
|     "build:mermaid": "pnpm build:vite --mermaid", |     "build:esbuild": "pnpm run -r clean && ts-node-esm --transpileOnly .esbuild/build.ts", | ||||||
|     "build:viz": "pnpm build:mermaid --visualize", |     "build:mermaid": "pnpm build:esbuild --mermaid", | ||||||
|  |     "build:viz": "pnpm build:esbuild --visualize", | ||||||
|     "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: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:watch": "pnpm build:vite --watch", |     "dev": "ts-node-esm --transpileOnly .esbuild/server.ts", | ||||||
|     "build": "pnpm run -r clean && pnpm build:types && pnpm build:vite", |     "dev:vite": "ts-node-esm --transpileOnly .vite/server.ts", | ||||||
|     "dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .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 . && ts-node-esm scripts/fixCSpell.ts", |     "lint:fix": "eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && ts-node-esm scripts/fixCSpell.ts", | ||||||
| @@ -31,8 +31,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": "ts-node-esm scripts/coverage.ts", |     "coverage:merge": "ts-node-esm 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", | ||||||
| @@ -82,11 +82,12 @@ | |||||||
|     "@vitest/spy": "^0.33.0", |     "@vitest/spy": "^0.33.0", | ||||||
|     "@vitest/ui": "^0.33.0", |     "@vitest/ui": "^0.33.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", | ||||||
|     "cypress": "^12.10.0", |     "cypress": "^12.10.0", | ||||||
|     "cypress-image-snapshot": "^4.0.1", |     "cypress-image-snapshot": "^4.0.1", | ||||||
|     "esbuild": "^0.18.0", |     "esbuild": "^0.19.0", | ||||||
|     "eslint": "^8.39.0", |     "eslint": "^8.39.0", | ||||||
|     "eslint-config-prettier": "^8.8.0", |     "eslint-config-prettier": "^8.8.0", | ||||||
|     "eslint-plugin-cypress": "^2.13.2", |     "eslint-plugin-cypress": "^2.13.2", | ||||||
|   | |||||||
| @@ -43,8 +43,7 @@ | |||||||
|     "cytoscape-cose-bilkent": "^4.1.0", |     "cytoscape-cose-bilkent": "^4.1.0", | ||||||
|     "cytoscape-fcose": "^2.1.0", |     "cytoscape-fcose": "^2.1.0", | ||||||
|     "d3": "^7.0.0", |     "d3": "^7.0.0", | ||||||
|     "khroma": "^2.0.0", |     "khroma": "^2.0.0" | ||||||
|     "non-layered-tidy-tree-layout": "^2.0.2" |  | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@types/cytoscape": "^3.19.9", |     "@types/cytoscape": "^3.19.9", | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "mermaid", |   "name": "mermaid", | ||||||
|   "version": "10.3.1", |   "version": "11.0.0-alpha.2", | ||||||
|   "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", | ||||||
| @@ -59,8 +59,6 @@ | |||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@braintree/sanitize-url": "^6.0.1", |     "@braintree/sanitize-url": "^6.0.1", | ||||||
|     "@types/d3-scale": "^4.0.3", |  | ||||||
|     "@types/d3-scale-chromatic": "^3.0.0", |  | ||||||
|     "cytoscape": "^3.23.0", |     "cytoscape": "^3.23.0", | ||||||
|     "cytoscape-cose-bilkent": "^4.1.0", |     "cytoscape-cose-bilkent": "^4.1.0", | ||||||
|     "cytoscape-fcose": "^2.1.0", |     "cytoscape-fcose": "^2.1.0", | ||||||
| @@ -73,14 +71,14 @@ | |||||||
|     "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", | ||||||
|  |     "@types/d3-scale": "^4.0.3", | ||||||
|  |     "@types/d3-scale-chromatic": "^3.0.0", | ||||||
|     "@types/cytoscape": "^3.19.9", |     "@types/cytoscape": "^3.19.9", | ||||||
|     "@types/d3": "^7.4.0", |     "@types/d3": "^7.4.0", | ||||||
|     "@types/d3-sankey": "^0.12.1", |     "@types/d3-sankey": "^0.12.1", | ||||||
|   | |||||||
							
								
								
									
										662
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										662
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user