Merge branch 'develop' into sidv/vitest

* develop: (28 commits)
  fix(docs): update link
  Revert "unify Jison tranformers"
  Update yarn.lock
  Revert "fix(test): No esm exports"
  fix(test): No esm exports
  fix(docs): `mmd` detection
  Hope this fails
  unify Jison tranformers
  Fix jest
  Remove `docs:build` from postbuild.
  Add verification log
  This should fail CI
  fix: imports in HTML
  Revert "Add diagramAPI to outfile"
  Add `type: module` to package.json
  chore(deps-dev): bump @types/lodash from 4.14.184 to 4.14.185
  Update integrations.md
  Add vitepress pluin
  Update mermaid version
  Fix ports
  ...
This commit is contained in:
Sidharth Vinod 2022-09-21 12:15:45 +05:30
commit 533da47516
No known key found for this signature in database
GPG Key ID: FB5CCD378D3907CD
35 changed files with 783 additions and 1727 deletions

View File

@ -13,8 +13,8 @@ build(iifeBuild({ minify: false, watch })).catch(handler);
build(esmBuild({ minify: false, watch })).catch(handler); build(esmBuild({ minify: false, watch })).catch(handler);
// mermaid.min.js // mermaid.min.js
build(esmBuild()).catch(handler);
// mermaid.esm.min.mjs
build(iifeBuild()).catch(handler); build(iifeBuild()).catch(handler);
// mermaid.esm.min.mjs
build(esmBuild()).catch(handler);
// mermaid.core.mjs (node_modules unbundled) // mermaid.core.mjs (node_modules unbundled)
build(esmCoreBuild()).catch(handler); build(esmCoreBuild()).catch(handler);

View File

@ -0,0 +1,14 @@
const { Generator } = require('jison');
exports.transformJison = (src) => {
const parser = new Generator(src, {
moduleType: 'js',
'token-stack': true,
});
const source = parser.generate({ moduleMain: '() => {}' });
const exporter = `
parser.parser = parser;
export { parser };
export default parser;
`;
return `${source} ${exporter}`;
};

View File

@ -1,38 +1,38 @@
const esbuild = require('esbuild'); const esbuild = require('esbuild');
const http = require('http'); const http = require('http');
const path = require('path'); const { iifeBuild, esmBuild } = require('./util.cjs');
const { iifeBuild } = require('./util.cjs'); const express = require('express');
// Start esbuild's server on a random local port // Start 2 esbuild servers. One for IIFE and one for ESM
esbuild // Serve 2 static directories: demo & cypress/platform
.serve( // Have 3 entry points:
{ // mermaid: './src/mermaid',
servedir: path.join(__dirname, '..'), // e2e: './cypress/platform/viewer.js',
// 'bundle-test': './cypress/platform/bundle-test.js',
const getEntryPointsAndExtensions = (format) => {
return {
entryPoints: {
mermaid: './src/mermaid',
e2e: 'cypress/platform/viewer.js',
'bundle-test': 'cypress/platform/bundle-test.js',
}, },
iifeBuild({ minify: false }) outExtension: { '.js': format === 'iife' ? '.js' : '.esm.mjs' },
) };
.then((result) => { };
// The result tells us where esbuild's local server is
const { host, port } = result;
// Then start a proxy server on port 3000 const generateHandler = (server) => {
http return (req, res) => {
.createServer((req, res) => {
if (req.url.includes('mermaid.js')) {
req.url = '/dist/mermaid.js';
}
const options = { const options = {
hostname: host, hostname: server.host,
port: port, port: server.port,
path: req.url, path: req.url,
method: req.method, method: req.method,
headers: req.headers, headers: req.headers,
}; };
// Forward each incoming request to esbuild // Forward each incoming request to esbuild
const proxyReq = http.request(options, (proxyRes) => { const proxyReq = http.request(options, (proxyRes) => {
// If esbuild returns "not found", send a custom 404 page // If esbuild returns "not found", send a custom 404 page
console.error('pp', req.url);
if (proxyRes.statusCode === 404) { if (proxyRes.statusCode === 404) {
if (!req.url.endsWith('.html')) { if (!req.url.endsWith('.html')) {
res.writeHead(404, { 'Content-Type': 'text/html' }); res.writeHead(404, { 'Content-Type': 'text/html' });
@ -40,14 +40,40 @@ esbuild
return; return;
} }
} }
// Otherwise, forward the response from esbuild to the client // Otherwise, forward the response from esbuild to the client
res.writeHead(proxyRes.statusCode, proxyRes.headers); res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res, { end: true }); proxyRes.pipe(res, { end: true });
}); });
// Forward the body of the request to esbuild // Forward the body of the request to esbuild
req.pipe(proxyReq, { end: true }); req.pipe(proxyReq, { end: true });
}) };
.listen(3000); };
(async () => {
const iifeServer = await esbuild.serve(
{},
{
...iifeBuild({ minify: false, outfile: undefined, outdir: 'dist' }),
...getEntryPointsAndExtensions('iife'),
}
);
const esmServer = await esbuild.serve(
{},
{
...esmBuild({ minify: false, outfile: undefined, outdir: 'dist' }),
...getEntryPointsAndExtensions('esm'),
}
);
const app = express();
app.use(express.static('demos'));
app.use(express.static('cypress/platform'));
app.all('/mermaid.js', generateHandler(iifeServer));
app.all('/mermaid.esm.mjs', generateHandler(esmServer));
app.all('/e2e.esm.mjs', generateHandler(esmServer));
app.all('/bundle-test.esm.mjs', generateHandler(esmServer));
app.listen(9000, () => {
console.log(`Listening on http://localhost:9000`);
}); });
})();

View File

@ -1,4 +1,4 @@
const { Generator } = require('jison'); const { transformJison } = require('./jisonTransformer.cjs');
const fs = require('fs'); const fs = require('fs');
const { dependencies } = require('../package.json'); const { dependencies } = require('../package.json');
@ -17,21 +17,16 @@ const buildOptions = (override = {}) => {
globalName: 'mermaid', globalName: 'mermaid',
platform: 'browser', platform: 'browser',
tsconfig: 'tsconfig.json', tsconfig: 'tsconfig.json',
resolveExtensions: ['.ts', '.js', '.json', '.jison'], resolveExtensions: ['.ts', '.js', '.mjs', '.json', '.jison'],
external: ['require', 'fs', 'path'], external: ['require', 'fs', 'path'],
outdir: 'dist', entryPoints: ['src/mermaid.ts'],
outfile: 'dist/mermaid.min.js',
plugins: [jisonPlugin], plugins: [jisonPlugin],
sourcemap: 'external', sourcemap: 'external',
...override, ...override,
}; };
}; };
const getOutFiles = (extension) => {
return {
[`mermaid${extension}`]: 'src/mermaid.ts',
[`diagramAPI${extension}`]: 'src/diagram-api/diagramAPI.ts',
};
};
/** /**
* Build options for mermaid.esm.* build. * Build options for mermaid.esm.* build.
* *
@ -43,8 +38,7 @@ const getOutFiles = (extension) => {
exports.esmBuild = (override = { minify: true }) => { exports.esmBuild = (override = { minify: true }) => {
return buildOptions({ return buildOptions({
format: 'esm', format: 'esm',
entryPoints: getOutFiles(`.esm${override.minify ? '.min' : ''}`), outfile: `dist/mermaid.esm${override.minify ? '.min' : ''}.mjs`,
outExtension: { '.js': '.mjs' },
...override, ...override,
}); });
}; };
@ -61,8 +55,7 @@ exports.esmBuild = (override = { minify: true }) => {
exports.esmCoreBuild = (override) => { exports.esmCoreBuild = (override) => {
return buildOptions({ return buildOptions({
format: 'esm', format: 'esm',
entryPoints: getOutFiles(`.core`), outfile: `dist/mermaid.core.mjs`,
outExtension: { '.js': '.mjs' },
external: ['require', 'fs', 'path', ...Object.keys(dependencies)], external: ['require', 'fs', 'path', ...Object.keys(dependencies)],
platform: 'neutral', platform: 'neutral',
...override, ...override,
@ -79,8 +72,11 @@ exports.esmCoreBuild = (override) => {
*/ */
exports.iifeBuild = (override = { minify: true }) => { exports.iifeBuild = (override = { minify: true }) => {
return buildOptions({ return buildOptions({
entryPoints: getOutFiles(override.minify ? '.min' : ''), outfile: `dist/mermaid${override.minify ? '.min' : ''}.js`,
format: 'iife', format: 'iife',
footer: {
js: 'mermaid = mermaid.default;',
},
...override, ...override,
}); });
}; };
@ -91,9 +87,7 @@ const jisonPlugin = {
build.onLoad({ filter: /\.jison$/ }, async (args) => { build.onLoad({ filter: /\.jison$/ }, async (args) => {
// Load the file from the file system // Load the file from the file system
const source = await fs.promises.readFile(args.path, 'utf8'); const source = await fs.promises.readFile(args.path, 'utf8');
const contents = new Generator(source, { 'token-stack': true }).generate({ const contents = transformJison(source);
moduleMain: '() => {}', // disable moduleMain (default one requires Node.JS modules)
});
return { contents, warnings: [] }; return { contents, warnings: [] };
}); });
}, },

View File

@ -40,18 +40,3 @@ jobs:
- name: Verify Docs - name: Verify Docs
run: yarn docs:verify run: yarn docs:verify
- name: Check no `console.log()` in .jison files
# ESLint can't parse .jison files directly
# In the future, it might be worth making a `eslint-plugin-jison`, so
# that this will be built into the `yarn lint` command.
run: |
shopt -s globstar
mkdir -p tmp/
for jison_file in src/**/*.jison; do
outfile="tmp/$(basename -- "$jison_file" .jison)-jison.js"
echo "Converting $jison_file to $outfile"
# default module-type (CJS) always adds a console.log()
yarn jison "$jison_file" --outfile "$outfile" --module-type "amd"
done
yarn eslint --no-eslintrc --rule no-console:error --parser "@babel/eslint-parser" "./tmp/*-jison.js"

View File

@ -1,5 +1,6 @@
{ {
"src/docs/**": ["yarn docs:build --git"], "src/docs/**": ["yarn docs:build --git"],
"src/docs.mts": ["yarn docs:build --git"], "src/docs.mts": ["yarn docs:build --git"],
"*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"] "*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"],
"*.jison": ["yarn lint:jison"]
} }

View File

@ -1,25 +0,0 @@
const { Generator } = require('jison');
const validate = require('schema-utils');
const schema = {
title: 'Jison Parser options',
type: 'object',
properties: {
'token-stack': {
type: 'boolean',
},
debug: {
type: 'boolean',
},
},
additionalProperties: false,
};
module.exports = function jisonLoader(source) {
const options = this.getOptions();
(validate.validate || validate)(schema, options, {
name: 'Jison Loader',
baseDataPath: 'options',
});
return new Generator(source, options).generate();
};

View File

@ -1,46 +0,0 @@
import { merge, mergeWithCustomize, customizeObject } from 'webpack-merge';
import nodeExternals from 'webpack-node-externals';
import baseConfig from './webpack.config.base';
export default (_env, args) => {
return [
// non-minified
merge(baseConfig, {
optimization: {
minimize: false,
},
}),
// core [To be used by webpack/esbuild/vite etc to bundle mermaid]
merge(baseConfig, {
externals: [nodeExternals()],
output: {
filename: '[name].core.js',
},
optimization: {
minimize: false,
},
}),
// umd
merge(baseConfig, {
output: {
filename: '[name].min.js',
},
}),
// esm
mergeWithCustomize({
customizeObject: customizeObject({
'output.library': 'replace',
}),
})(baseConfig, {
experiments: {
outputModule: true,
},
output: {
library: {
type: 'module',
},
filename: '[name].esm.min.mjs',
},
}),
];
};

View File

@ -1,71 +0,0 @@
import path from 'path';
const esbuild = require('esbuild');
const { ESBuildMinifyPlugin } = require('esbuild-loader');
export const resolveRoot = (...relativePath) => path.resolve(__dirname, '..', ...relativePath);
export default {
amd: false, // https://github.com/lodash/lodash/issues/3052
target: 'web',
entry: {
mermaid: './src/mermaid',
},
resolve: {
extensions: ['.wasm', '.mjs', '.js', '.ts', '.json', '.jison'],
fallback: {
fs: false, // jison generated code requires 'fs'
path: require.resolve('path-browserify'),
},
},
output: {
path: resolveRoot('./dist'),
filename: '[name].js',
library: {
name: 'mermaid',
type: 'umd',
export: 'default',
},
globalObject: 'typeof self !== "undefined" ? self : this',
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.js$/,
include: [resolveRoot('./src'), resolveRoot('./node_modules/dagre-d3-renderer/lib')],
use: {
loader: 'esbuild-loader',
options: {
implementation: esbuild,
target: 'es2015',
},
},
},
{
// load scss to string
test: /\.scss$/,
use: ['css-to-string-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.jison$/,
use: {
loader: path.resolve(__dirname, './loaders/jison.js'),
options: {
'token-stack': true,
},
},
},
],
},
devtool: 'source-map',
optimization: {
minimizer: [
new ESBuildMinifyPlugin({
target: 'es2015',
}),
],
},
};

View File

@ -1,26 +0,0 @@
import baseConfig, { resolveRoot } from './webpack.config.base';
import { merge } from 'webpack-merge';
export default merge(baseConfig, {
mode: 'development',
entry: {
mermaid: './src/mermaid',
e2e: './cypress/platform/viewer.js',
'bundle-test': './cypress/platform/bundle-test.js',
},
output: {
globalObject: 'window',
},
devServer: {
compress: true,
port: 9000,
static: [
{ directory: resolveRoot('cypress', 'platform') },
{ directory: resolveRoot('dist') },
{ directory: resolveRoot('demos') },
],
},
externals: {
mermaid: 'mermaid',
},
});

View File

@ -1,10 +0,0 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: 'defaults, ie >= 11, current node',
},
],
],
};

View File

@ -2,7 +2,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<!-- <meta charset="iso-8859-15"/> --> <!-- <meta charset="iso-8859-15"/> -->
<script src="/e2e.js"></script> <script src="/e2e.esm.mjs" type="module"></script>
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> --> <!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
<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"
@ -37,7 +37,7 @@
</style> </style>
</head> </head>
<body> <body>
<script src="./mermaid.js"></script> <!-- <script src="./mermaid.js"></script> -->
<script> <script>
// Notice startOnLoad=false // Notice startOnLoad=false
// This prevents default handling in mermaid from render before the e2e logic is applied // This prevents default handling in mermaid from render before the e2e logic is applied

View File

@ -3,7 +3,8 @@ import mermaid2 from '../../src/mermaid';
/** /**
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches * ##contentLoaded Callback function that is called when page is loaded. This functions fetches
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the page. * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
* page.
*/ */
const contentLoaded = function () { const contentLoaded = function () {
let pos = document.location.href.indexOf('?graph='); let pos = document.location.href.indexOf('?graph=');
@ -32,8 +33,8 @@ const contentLoaded = function () {
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
} }
global.mermaid.initialize(graphObj.mermaid); mermaid2.initialize(graphObj.mermaid);
global.mermaid.init(); mermaid2.init();
} }
}; };

View File

@ -12,6 +12,6 @@
</head> </head>
<body> <body>
<div id="graph-to-be"></div> <div id="graph-to-be"></div>
<script src="./bundle-test.js" charset="utf-8"></script> <script src="./bundle-test.esm.mjs" type="module" charset="utf-8"></script>
</body> </body>
</html> </html>

View File

@ -1,6 +1,6 @@
<html> <html>
<head> <head>
<script src="/e2e.js"></script> <script src="/e2e.esm.mjs" 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 {

View File

@ -23,8 +23,8 @@ ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
</pre> </pre>
<script src="./mermaid.js"></script> <script type="module">
<script> import mermaid from './mermaid.esm.mjs';
mermaid.initialize({ mermaid.initialize({
theme: 'forest', theme: 'forest',
// themeCSS: '.node rect { fill: red; }', // themeCSS: '.node rect { fill: red; }',

View File

@ -77,7 +77,19 @@ When deployed within code, init is called before the graph/diagram description.
**for example**: **for example**:
```mmd ```mermaid-example
%%{init: {"theme": "default", "logLevel": 1 }}%%
graph LR
a-->b
b-->c
c-->d
d-->e
e-->f
f-->g
g-->
```
```mermaid
%%{init: {"theme": "default", "logLevel": 1 }}%% %%{init: {"theme": "default", "logLevel": 1 }}%%
graph LR graph LR
a-->b a-->b

View File

@ -42,7 +42,13 @@ It is also possible to override site-wide theme settings locally, for a specific
**Following is an example:** **Following is an example:**
```mmd ```mermaid-example
%%{init: {'theme':'base'}}%%
graph TD
a --> b
```
```mermaid
%%{init: {'theme':'base'}}%% %%{init: {'theme':'base'}}%%
graph TD graph TD
a --> b a --> b
@ -58,7 +64,25 @@ The easiest way to make a custom theme is to start with the base theme, and just
Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`. Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
```mmd ```mermaid-example
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%% %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)

View File

@ -49,7 +49,15 @@ In our release process we rely heavily on visual regression tests using [applito
### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax) ### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax)
```mmd ```mermaid-example
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```
```mermaid
graph TD; graph TD;
A-->B; A-->B;
A-->C; A-->C;
@ -61,7 +69,21 @@ graph TD;
### [Sequence diagram](./sequenceDiagram.md) ### [Sequence diagram](./sequenceDiagram.md)
```mmd ```mermaid-example
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts <br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob
@ -79,7 +101,20 @@ sequenceDiagram
### [Gantt diagram](./gantt.md) ### [Gantt diagram](./gantt.md)
```mmd ```mermaid-example
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram to mermaid
excludes weekdays 2014-01-10
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
```
```mermaid
gantt gantt
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
title Adding GANTT diagram to mermaid title Adding GANTT diagram to mermaid
@ -96,7 +131,24 @@ Future task2 : des4, after des3, 5d
### [Class diagram](./classDiagram.md) ### [Class diagram](./classDiagram.md)
```mmd ```mermaid-example
classDiagram
Class01 <|-- AveryLongClass : Cool
Class03 *-- Class04
Class05 o-- Class06
Class07 .. Class08
Class09 --> C2 : Where am i?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
Class08 <--> C2: Cool label
```
```mermaid
classDiagram classDiagram
Class01 <|-- AveryLongClass : Cool Class01 <|-- AveryLongClass : Cool
Class03 *-- Class04 Class03 *-- Class04
@ -145,7 +197,15 @@ Class08 <--> C2: Cool label
### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md) ### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md)
```mmd ```mermaid-example
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
```mermaid
erDiagram erDiagram
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains ORDER ||--|{ LINE-ITEM : contains
@ -157,7 +217,19 @@ erDiagram
### [User Journey Diagram](./user-journey.md) ### [User Journey Diagram](./user-journey.md)
```mmd ```mermaid-example
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
```
```mermaid
journey journey
title My working day title My working day
section Go to work section Go to work

View File

@ -336,7 +336,12 @@ classE o-- classF : aggregation
Relations can logically represent an N:M association: Relations can logically represent an N:M association:
```mmd ```mermaid-example
classDiagram
Animal <|--|> Zebra
```
```mermaid
classDiagram classDiagram
Animal <|--|> Zebra Animal <|--|> Zebra
``` ```
@ -468,7 +473,17 @@ class Color{
Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including any class diagram syntax. Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including any class diagram syntax.
```mmd ```mermaid-example
classDiagram
%% This whole line is a comment classDiagram class Shape <<interface>>
class Shape{
<<interface>>
noOfVertices
draw()
}
```
```mermaid
classDiagram classDiagram
%% This whole line is a comment classDiagram class Shape <<interface>> %% This whole line is a comment classDiagram class Shape <<interface>>
class Shape{ class Shape{
@ -538,7 +553,15 @@ You would define these actions on a separate line after all classes have been de
_URL Link:_ _URL Link:_
```mmd ```mermaid-example
classDiagram
class Shape
link Shape "https://www.github.com" "This is a tooltip for a link"
class Shape2
click Shape2 href "https://www.github.com" "This is a tooltip for a link"
```
```mermaid
classDiagram classDiagram
class Shape class Shape
link Shape "https://www.github.com" "This is a tooltip for a link" link Shape "https://www.github.com" "This is a tooltip for a link"
@ -548,7 +571,15 @@ click Shape2 href "https://www.github.com" "This is a tooltip for a link"
_Callback:_ _Callback:_
```mmd ```mermaid-example
classDiagram
class Shape
callback Shape "callbackFunction" "This is a tooltip for a callback"
class Shape2
click Shape2 call callbackFunction() "This is a tooltip for a callback"
```
```mermaid
classDiagram classDiagram
class Shape class Shape
callback Shape "callbackFunction" "This is a tooltip for a callback" callback Shape "callbackFunction" "This is a tooltip for a callback"

View File

@ -397,7 +397,15 @@ graph TB
If you describe the same diagram using the the basic syntax, it will take four lines: If you describe the same diagram using the the basic syntax, it will take four lines:
```mmd ```mermaid-example
graph TB
A --> C
A --> D
B --> C
B --> D
```
```mermaid
graph TB graph TB
A --> C A --> C
A --> D A --> D
@ -740,7 +748,13 @@ Beginner's tip—here's a full example of using interactive links in HTML:
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including all punctuation and any flow syntax. Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including all punctuation and any flow syntax.
```mmd ```mermaid-example
graph LR
%% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C
```
```mermaid
graph LR graph LR
%% this is a comment A -- text --> B{node} %% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C

View File

@ -114,7 +114,13 @@ Cardinality is a property that describes how many elements of another entity can
Relationships may be classified as either _identifying_ or _non-identifying_ and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line: Relationships may be classified as either _identifying_ or _non-identifying_ and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
```mmd ```mermaid-example
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is
```
```mermaid
erDiagram erDiagram
CAR ||--o{ NAMED-DRIVER : allows CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is PERSON ||--o{ NAMED-DRIVER : is

View File

@ -403,7 +403,15 @@ word of warning, one could go overboard with this making the flowchart harder to
markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little. markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little.
This goes for expressive syntaxes as well. This goes for expressive syntaxes as well.
```mmd ```mermaid-example
flowchart TB
A --> C
A --> D
B --> C
B --> D
```
```mermaid
flowchart TB flowchart TB
A --> C A --> C
A --> D A --> D
@ -778,7 +786,13 @@ Beginner's tip—a full example using interactive links in a html context:
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax
```mmd ```mermaid-example
flowchart LR
%% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C
```
```mermaid
flowchart LR flowchart LR
%% this is a comment A -- text --> B{node} %% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C

View File

@ -234,7 +234,21 @@ More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
```mmd ```mermaid-example
gantt
title A Gantt Diagram
%% this is a comment
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
```
```mermaid
gantt gantt
title A Gantt Diagram title A Gantt Diagram
%% this is a comment %% this is a comment

View File

@ -51,6 +51,8 @@ They also serve as proof of concept, for the variety of things that can be built
## CMS ## CMS
- [VitePress](https://vitepress.vuejs.org/)
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
- [VuePress](https://vuepress.vuejs.org/) - [VuePress](https://vuepress.vuejs.org/)
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs) - [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
- [Grav CMS](https://getgrav.org/) - [Grav CMS](https://getgrav.org/)

View File

@ -481,7 +481,14 @@ sequenceDiagram
Comments can be entered within a sequence diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a sequence diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
```mmd ```mermaid-example
sequenceDiagram
Alice->>John: Hello John, how are you?
%% this is a comment
John-->>Alice: Great!
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->>John: Hello John, how are you? Alice->>John: Hello John, how are you?
%% this is a comment %% this is a comment
@ -554,7 +561,20 @@ This can be configured by adding one or more link lines with the format:
link <actor>: <link-label> @ <link-url> link <actor>: <link-label> @ <link-url>
```mmd ```mermaid-example
sequenceDiagram
participant Alice
participant John
link Alice: Dashboard @ https://dashboard.contoso.com/alice
link Alice: Wiki @ https://wiki.contoso.com/alice
link John: Dashboard @ https://dashboard.contoso.com/john
link John: Wiki @ https://wiki.contoso.com/john
Alice->>John: Hello John, how are you?
John-->>Alice: Great!
Alice-)John: See you later!
```
```mermaid
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant John participant John

View File

@ -403,7 +403,18 @@ stateDiagram
Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
```mmd ```mermaid-example
stateDiagram-v2
[*] --> Still
Still --> [*]
%% this is a comment
Still --> Moving
Moving --> Still %% another comment
Moving --> Crash
Crash --> [*]
```
```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> Still [*] --> Still
Still --> [*] Still --> [*]

View File

@ -41,7 +41,13 @@ mermaidAPI.initialize({
When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array. When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array.
```mmd ```mermaid-example
%%{init: {'theme':'base'}}%%
graph TD
a --> b
```
```mermaid
%%{init: {'theme':'base'}}%% %%{init: {'theme':'base'}}%%
graph TD graph TD
a --> b a --> b
@ -329,7 +335,25 @@ In the following examples, the directive `init` is used, with the `theme` being
### Flowchart ### Flowchart
```mmd ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)

View File

@ -5,6 +5,7 @@
"main": "dist/mermaid.core.mjs", "main": "dist/mermaid.core.mjs",
"module": "dist/mermaid.core.mjs", "module": "dist/mermaid.core.mjs",
"types": "dist/mermaid.d.ts", "types": "dist/mermaid.d.ts",
"type": "module",
"exports": { "exports": {
".": { ".": {
"require": "./dist/mermaid.min.js", "require": "./dist/mermaid.min.js",
@ -26,22 +27,20 @@
"clean": "rimraf dist", "clean": "rimraf dist",
"build:code": "node .esbuild/esbuild.cjs", "build:code": "node .esbuild/esbuild.cjs",
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly", "build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
"build:webpack": "webpack --mode production --progress --color",
"build:watch": "yarn build:code --watch", "build:watch": "yarn build:code --watch",
"build:new": "concurrently \"yarn build:code\" \"yarn build:types\"", "build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
"build": "yarn clean; yarn build:webpack", "build": "yarn clean; yarn build:esbuild",
"dev": "node .esbuild/serve.cjs",
"docs:build": "ts-node-esm src/docs.mts", "docs:build": "ts-node-esm src/docs.mts",
"docs:verify": "ts-node-esm src/docs.mts --verify", "docs:verify": "yarn docs:build --verify",
"postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md && yarn docs:build", "postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
"release": "yarn build", "release": "yarn build",
"lint": "eslint --cache --ignore-path .gitignore . && prettier --check .", "lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .", "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
"e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js", "lint:jison": "ts-node-esm src/jison/lint.mts",
"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-upd": "yarn lint && jest e2e -u --config e2e/jest.config.js",
"dev": "webpack serve --config ./.webpack/webpack.config.e2e.babel.js",
"ci": "vitest run", "ci": "vitest run",
"test": "yarn lint && vitest run", "test": "yarn lint && vitest run",
"test:watch": "vitest --coverage --watch", "test:watch": "vitest --coverage --watch",
@ -81,31 +80,26 @@
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.25.7", "@applitools/eyes-cypress": "^3.25.7",
"@babel/core": "^7.19.0",
"@babel/eslint-parser": "^7.14.7",
"@babel/preset-env": "^7.19.0",
"@babel/register": "^7.14.5",
"@commitlint/cli": "^17.1.2", "@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.0.0", "@commitlint/config-conventional": "^17.0.0",
"@types/d3": "^7.4.0", "@types/d3": "^7.4.0",
"@types/dompurify": "^2.3.4", "@types/dompurify": "^2.3.4",
"@types/eslint": "^8.4.6",
"@types/express": "^4.17.13",
"@types/jsdom": "^20.0.0", "@types/jsdom": "^20.0.0",
"@types/lodash": "^4.14.184", "@types/lodash": "^4.14.185",
"@types/prettier": "^2.7.0", "@types/prettier": "^2.7.0",
"@types/stylis": "^4.0.2", "@types/stylis": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0", "@typescript-eslint/parser": "^5.37.0",
"@vitest/coverage-c8": "^0.23.2", "@vitest/coverage-c8": "^0.23.2",
"@vitest/ui": "^0.23.2", "@vitest/ui": "^0.23.2",
"babel-loader": "^8.2.2",
"concurrently": "^7.4.0", "concurrently": "^7.4.0",
"coveralls": "^3.1.1", "coveralls": "^3.1.1",
"css-to-string-loader": "^0.1.3",
"cypress": "^10.0.0", "cypress": "^10.0.0",
"cypress-image-snapshot": "^4.0.1", "cypress-image-snapshot": "^4.0.1",
"documentation": "13.2.0", "documentation": "13.2.0",
"esbuild": "^0.15.6", "esbuild": "^0.15.6",
"esbuild-loader": "^2.19.0",
"eslint": "^8.23.1", "eslint": "^8.23.1",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-cypress": "^2.12.1", "eslint-plugin-cypress": "^2.12.1",
@ -114,6 +108,7 @@
"eslint-plugin-jsdoc": "^39.3.6", "eslint-plugin-jsdoc": "^39.3.6",
"eslint-plugin-json": "^3.1.0", "eslint-plugin-json": "^3.1.0",
"eslint-plugin-markdown": "^3.0.0", "eslint-plugin-markdown": "^3.0.0",
"express": "^4.18.1",
"globby": "^13.1.2", "globby": "^13.1.2",
"husky": "^8.0.0", "husky": "^8.0.0",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
@ -128,17 +123,10 @@
"remark": "^14.0.2", "remark": "^14.0.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"start-server-and-test": "^1.12.6", "start-server-and-test": "^1.12.6",
"terser-webpack-plugin": "^5.3.6",
"ts-loader": "^9.3.1",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^4.8.3", "typescript": "^4.8.3",
"unist-util-flatmap": "^1.0.0", "unist-util-flatmap": "^1.0.0",
"vitest": "^0.23.1", "vitest": "^0.23.1"
"webpack": "^5.53.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^4.11.0",
"webpack-merge": "^5.8.0",
"webpack-node-externals": "^3.0.0"
}, },
"resolutions": { "resolutions": {
"d3": "^7.0.0" "d3": "^7.0.0"

View File

@ -1,11 +1,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
/** /**
* @file Transform documentation source files into files suitable for publishing * @file Transform documentation source files into files suitable for publishing and optionally copy
* and optionally copy the transformed files from the source directory to the * the transformed files from the source directory to the directory used for the final, published
* directory used for the final, published documentation directory. The list * documentation directory. The list of files transformed and copied to final documentation
* of files transformed and copied to final documentation directory are logged * directory are logged to the console. If a file in the source directory has the same contents in
* to the console. If a file in the source directory has the same contents in
* the final directory, nothing is done (the final directory is up-to-date). * the final directory, nothing is done (the final directory is up-to-date).
* @example * @example
* docs * docs
@ -24,12 +23,12 @@
* If the --git option is used, the command `git add docs` will be run after all transformations (and/or verifications) have completed successfully * If the --git option is used, the command `git add docs` will be run after all transformations (and/or verifications) have completed successfully
* If not files were transformed, the git command is not run. * If not files were transformed, the git command is not run.
* *
* @todo Ensure that the documentation source and final paths are correct by * @todo Ensure that the documentation source and final paths are correct by using process.cwd() to
* using process.cwd() to get their absolute paths. Ensures that the location * get their absolute paths. Ensures that the location of those 2 directories is not dependent on
* of those 2 directories is not dependent on where this file resides. * where this file resides.
* *
* @todo Write a test file for this. (Will need to be able to deal .mts file. * @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with
* Jest has trouble with it.) * it.)
*/ */
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
import { exec } from 'child_process'; import { exec } from 'child_process';
@ -68,14 +67,13 @@ const prettierConfig: prettier.Config = {
let filesWereTransformed = false; let filesWereTransformed = false;
/** /**
* Given a source file name and path, return the documentation destination full * Given a source file name and path, return the documentation destination full path and file name
* path and file name Create the destination path if it does not already exist. * Create the destination path if it does not already exist.
* *
* @param {string} file - Name of the file (including full path) * @param {string} file - Name of the file (including full path)
* @returns {string} Name of the file with the path changed from the source * @returns {string} Name of the file with the path changed from the source directory to final
* directory to final documentation directory * documentation directory
* @todo Possible Improvement: combine with lint-staged to only copy files that * @todo Possible Improvement: combine with lint-staged to only copy files that have changed
* have changed
*/ */
const changeToFinalDocDir = (file: string): string => { const changeToFinalDocDir = (file: string): string => {
const newDir = file.replace(SOURCE_DOCS_DIR, FINAL_DOCS_DIR); const newDir = file.replace(SOURCE_DOCS_DIR, FINAL_DOCS_DIR);
@ -84,8 +82,8 @@ const changeToFinalDocDir = (file: string): string => {
}; };
/** /**
* Log messages to the console showing if the transformed file copied to the * Log messages to the console showing if the transformed file copied to the final documentation
* final documentation directory or still needs to be copied. * directory or still needs to be copied.
* *
* @param {string} filename Name of the file that was transformed * @param {string} filename Name of the file that was transformed
* @param {boolean} wasCopied Whether or not the file was copied * @param {boolean} wasCopied Whether or not the file was copied
@ -101,14 +99,13 @@ const logWasOrShouldBeTransformed = (filename: string, wasCopied: boolean) => {
}; };
/** /**
* If the file contents were transformed, set the _filesWereTransformed_ flag to * If the file contents were transformed, set the _filesWereTransformed_ flag to true and copy the
* true and copy the transformed contents to the final documentation directory * transformed contents to the final documentation directory if the doCopy flag is true. Log
* if the doCopy flag is true. Log messages to the console. * messages to the console.
* *
* @param {string} filename Name of the file that will be verified * @param {string} filename Name of the file that will be verified
* @param {boolean} [doCopy=false] Whether we should copy that * @param {boolean} [doCopy=false] Whether we should copy that transformedContents to the final
* transformedContents to the final documentation directory. Default is * documentation directory. Default is `false`
* `false`. Default is `false`
* @param {string} [transformedContent] New contents for the file * @param {string} [transformedContent] New contents for the file
*/ */
const copyTransformedContents = (filename: string, doCopy = false, transformedContent?: string) => { const copyTransformedContents = (filename: string, doCopy = false, transformedContent?: string) => {
@ -133,15 +130,14 @@ const readSyncedUTF8file = (filename: string): string => {
}; };
/** /**
* Transform a markdown file and write the transformed file to the directory for * Transform a markdown file and write the transformed file to the directory for published
* published documentation * documentation
* *
* 1. Add a `mermaid-example` block before every `mermaid` or `mmd` block On the * 1. Add a `mermaid-example` block before every `mermaid` or `mmd` block On the docsify site (one
* docsify site (one place where the documentation is published), this will * place where the documentation is published), this will show the code used for the mermaid
* show the code used for the mermaid diagram * diagram
* 2. Add the text that says the file is automatically generated * 2. Add the text that says the file is automatically generated
* 3. Use prettier to format the file Verify that the file has been changed and * 3. Use prettier to format the file Verify that the file has been changed and write out the changes
* write out the changes
* *
* @param file {string} name of the file that will be verified * @param file {string} name of the file that will be verified
*/ */
@ -149,12 +145,15 @@ const transformMarkdown = (file: string) => {
const doc = readSyncedUTF8file(file); const doc = readSyncedUTF8file(file);
const ast: Root = remark.parse(doc); const ast: Root = remark.parse(doc);
const out = flatmap(ast, (c: Code) => { const out = flatmap(ast, (c: Code) => {
if (c.type !== 'code' || !c.lang?.startsWith('mermaid')) { if (c.type !== 'code') {
return [c]; return [c];
} }
if (c.lang === 'mermaid' || c.lang === 'mmd') { if (c.lang === 'mermaid' || c.lang === 'mmd') {
c.lang = 'mermaid-example'; c.lang = 'mermaid-example';
} }
if (c.lang !== 'mermaid-example') {
return [c];
}
return [c, Object.assign({}, c, { lang: 'mermaid' })]; return [c, Object.assign({}, c, { lang: 'mermaid' })];
}); });
@ -168,11 +167,11 @@ const transformMarkdown = (file: string) => {
}; };
/** /**
* Transform an HTML file and write the transformed file to the directory for * Transform an HTML file and write the transformed file to the directory for published
* published documentation * documentation
* *
* - Add the text that says the file is automatically generated Verify that the * - Add the text that says the file is automatically generated Verify that the file has been changed
* file has been changed and write out the changes * and write out the changes
* *
* @param filename {string} name of the HTML file to transform * @param filename {string} name of the HTML file to transform
*/ */
@ -204,6 +203,9 @@ const transformHtml = (filename: string) => {
/** Main method (entry point) */ /** Main method (entry point) */
(async () => { (async () => {
if (verifyOnly) {
console.log('Verifying that all files are in sync with the source files');
}
const sourceDirGlob = join('.', SOURCE_DOCS_DIR, '**'); const sourceDirGlob = join('.', SOURCE_DOCS_DIR, '**');
const includeFilesStartingWithDot = true; const includeFilesStartingWithDot = true;

View File

@ -49,6 +49,8 @@ They also serve as proof of concept, for the variety of things that can be built
## CMS ## CMS
- [VitePress](https://vitepress.vuejs.org/)
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
- [VuePress](https://vuepress.vuejs.org/) - [VuePress](https://vuepress.vuejs.org/)
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs) - [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
- [Grav CMS](https://getgrav.org/) - [Grav CMS](https://getgrav.org/)

31
src/jison/lint.mts Normal file
View File

@ -0,0 +1,31 @@
/* eslint-disable no-console */
import { readFile } from 'fs/promises';
import { globby } from 'globby';
import { ESLint } from 'eslint';
// @ts-ignore no typings
import jison from 'jison';
const linter = new ESLint({
overrideConfig: { rules: { 'no-console': 'error' }, parser: '@typescript-eslint/parser' },
useEslintrc: false,
});
const lint = async (file: string): Promise<boolean> => {
const jisonCode = await readFile(file, 'utf8');
// @ts-ignore no typings
const jsCode = new jison.Generator(jisonCode, { moduleType: 'amd' }).generate();
const [result] = await linter.lintText(jsCode);
if (result.errorCount > 0) {
console.error(`Linting failed for ${file}`);
console.error(result.messages);
}
return result.errorCount === 0;
};
(async () => {
const jisonFiles = await globby(['./src/**/*.jison'], { dot: true });
const lintResults = await Promise.all(jisonFiles.map(lint));
if (lintResults.some((result) => result === false)) {
process.exit(1);
}
})();

1700
yarn.lock

File diff suppressed because it is too large Load Diff