Skip to content

Commit

Permalink
Merge 738abc8 into ee13c76
Browse files Browse the repository at this point in the history
  • Loading branch information
sidharthv96 committed Oct 8, 2022
2 parents ee13c76 + 738abc8 commit 9eb8a1e
Show file tree
Hide file tree
Showing 30 changed files with 163 additions and 555 deletions.
14 changes: 14 additions & 0 deletions cypress/platform/sidv.html
@@ -0,0 +1,14 @@
<html>
<body>
<pre class="mermaid">
none
hello world
</pre>
<script src="./mermaid.js"></script>
<script>
mermaid.initialize({
logLevel: 1,
});
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -47,7 +47,8 @@
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
"ci": "vitest run",
"test": "pnpm lint && vitest run",
"test:watch": "vitest --coverage --watch",
"test:watch": "vitest --watch",
"test:coverage": "vitest --coverage",
"prepublishOnly": "pnpm build && pnpm test",
"prepare": "concurrently \"husky install\" \"pnpm build\"",
"pre-commit": "lint-staged"
Expand Down
69 changes: 36 additions & 33 deletions packages/mermaid/src/Diagram.ts
Expand Up @@ -8,11 +8,18 @@ export class Diagram {
parser;
renderer;
db;
private detectTypeFailed = false;
// eslint-disable-next-line @typescript-eslint/ban-types
constructor(public txt: string, parseError?: Function) {
const cnf = configApi.getConfig();
this.txt = txt;
this.type = detectType(txt, cnf);
try {
this.type = detectType(txt, cnf);
} catch (e) {
this.handleError(e, parseError);
this.type = 'error';
this.detectTypeFailed = true;
}
const diagram = getDiagram(this.type);
log.debug('Type ' + this.type);
// Setup diagram
Expand All @@ -32,29 +39,37 @@ export class Diagram {

// eslint-disable-next-line @typescript-eslint/ban-types
parse(text: string, parseError?: Function): boolean {
if (this.detectTypeFailed) {
return false;
}
try {
text = text + '\n';
this.db.clear();
this.parser.parse(text);
return true;
} catch (error) {
// Is this the correct way to access mermiad's parseError()
// method ? (or global.mermaid.parseError()) ?
if (parseError) {
if (isDetailedError(error)) {
// handle case where error string and hash were
// wrapped in object like`const error = { str, hash };`
parseError(error.str, error.hash);
} else {
// assume it is just error string and pass it on
parseError(error);
}
this.handleError(error, parseError);
}
return false;
}

// eslint-disable-next-line @typescript-eslint/ban-types
handleError(error: unknown, parseError?: Function) {
// Is this the correct way to access mermiad's parseError()
// method ? (or global.mermaid.parseError()) ?
if (parseError) {
if (isDetailedError(error)) {
// handle case where error string and hash were
// wrapped in object like`const error = { str, hash };`
parseError(error.str, error.hash);
} else {
// No mermaid.parseError() handler defined, so re-throw it
throw error;
// assume it is just error string and pass it on
parseError(error);
}
} else {
// No mermaid.parseError() handler defined, so re-throw it
throw error;
}
return false;
}

getParser() {
Expand All @@ -66,10 +81,8 @@ export class Diagram {
}
}

export default Diagram;

// eslint-disable-next-line @typescript-eslint/ban-types
export const getDiagramFromText = async (txt: string, parseError?: Function) => {
export const getDiagramFromText = async (txt: string, parseError?: Function): Promise<Diagram> => {
const type = detectType(txt, configApi.getConfig());
try {
// Trying to find the diagram
Expand All @@ -79,24 +92,14 @@ export const getDiagramFromText = async (txt: string, parseError?: Function) =>
if (!loader) {
throw new Error(`Diagram ${type} not found.`);
}
// Diagram not avaiable, loading it
// const path = getPathForDiagram(type);
const { diagram } = await loader(); // eslint-disable-line @typescript-eslint/no-explicit-any
registerDiagram(
type,
{
db: diagram.db,
renderer: diagram.renderer,
parser: diagram.parser,
styles: diagram.styles,
},
diagram.injectUtils
);
// await loadDiagram('./packages/mermaid-mindmap/dist/mermaid-mindmap.js');
// await loadDiagram(path + 'mermaid-' + type + '.js');
// Diagram not available, loading it
const { diagram } = await loader();
registerDiagram(type, diagram, undefined, diagram.injectUtils);
// new diagram will try getDiagram again and if fails then it is a valid throw
}
// If either of the above worked, we have the diagram
// logic and can continue
return new Diagram(txt, parseError);
};

export default Diagram;
6 changes: 1 addition & 5 deletions packages/mermaid/src/__mocks__/mermaidAPI.ts
Expand Up @@ -11,17 +11,13 @@ import Diagram from '../Diagram';
// Normally, we could just do the following to get the original `parse()`
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.

let hasLoadedDiagrams = false;
/**
* @param text
* @param parseError
*/
// eslint-disable-next-line @typescript-eslint/ban-types
function parse(text: string, parseError?: Function): boolean {
if (!hasLoadedDiagrams) {
addDiagrams();
hasLoadedDiagrams = true;
}
addDiagrams();
const diagram = new Diagram(text, parseError);
return diagram.parse(text, parseError);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/config.type.ts
Expand Up @@ -3,7 +3,7 @@
import DOMPurify from 'dompurify';

export interface MermaidConfig {
lazyLoadedDiagrams?: any;
lazyLoadedDiagrams?: string[];
theme?: string;
themeVariables?: any;
themeCSS?: string;
Expand Down
23 changes: 9 additions & 14 deletions packages/mermaid/src/diagram-api/detectType.ts
@@ -1,8 +1,7 @@
import { MermaidConfig } from '../config.type';
import { log } from '../logger';
import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';

export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
export type DiagramLoader = (() => any) | null;
export type DetectorRecord = { detector: DiagramDetector; loader: DiagramLoader };
const directive =
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
const anyComment = /\s*%%.*\n/gm;
Expand Down Expand Up @@ -34,26 +33,22 @@ const detectors: Record<string, DetectorRecord> = {};
*/
export const detectType = function (text: string, config?: MermaidConfig): string {
text = text.replace(directive, '').replace(anyComment, '\n');

// console.log(detectors);

for (const [key, { detector }] of Object.entries(detectors)) {
const diagram = detector(text, config);
if (diagram) {
return key;
}
}
// TODO: #3391
// throw new Error(`No diagram type detected for text: ${text}`);
return 'flowchart';

throw new Error(`No diagram type detected for text: ${text}`);
};

export const addDetector = (
key: string,
detector: DiagramDetector,
loader: DiagramLoader | null
) => {
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
if (detectors[key]) {
throw new Error(`Detector with key ${key} already exists`);
}
detectors[key] = { detector, loader };
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
};

export const getDiagramLoader = (key: string) => detectors[key].loader;
67 changes: 24 additions & 43 deletions packages/mermaid/src/diagram-api/diagram-orchestration.ts
@@ -1,16 +1,4 @@
import {
registerDiagram,
registerDetector,
DiagramDefinition,
DiagramDetector,
} from './diagramAPI';

// // @ts-ignore: TODO Fix ts errors
// import mindmapParser from '../diagrams/mindmap/parser/mindmap';
// import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
// import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
// import mindmapStyles from '../diagrams/mindmap/styles';
import { registerDiagram } from './diagramAPI';

// @ts-ignore: TODO Fix ts errors
import gitGraphParser from '../diagrams/git/parser/gitGraph';
Expand Down Expand Up @@ -106,17 +94,15 @@ import { setConfig } from '../config';
import errorRenderer from '../diagrams/error/errorRenderer';
import errorStyles from '../diagrams/error/styles';

const registerDiagramAndDetector = (
id: string,
diagram: DiagramDefinition,
detector: DiagramDetector
) => {
registerDiagram(id, diagram);
registerDetector(id, detector);
};

let hasLoadedDiagrams = false;
export const addDiagrams = () => {
registerDiagramAndDetector(
if (hasLoadedDiagrams) {
return;
}
// This is added here to avoid race-conditions.
// We could optimize the loading logic somehow.
hasLoadedDiagrams = true;
registerDiagram(
'error',
// Special diagram with error messages but setup as a regular diagram
{
Expand All @@ -140,7 +126,7 @@ export const addDiagrams = () => {
(text) => text.toLowerCase().trim() === 'error'
);

registerDiagramAndDetector(
registerDiagram(
'c4',
{
parser: c4Parser,
Expand All @@ -153,7 +139,7 @@ export const addDiagrams = () => {
},
c4Detector
);
registerDiagramAndDetector(
registerDiagram(
'class',
{
parser: classParser,
Expand All @@ -170,7 +156,7 @@ export const addDiagrams = () => {
},
classDetector
);
registerDiagramAndDetector(
registerDiagram(
'classDiagram',
{
parser: classParser,
Expand All @@ -187,7 +173,7 @@ export const addDiagrams = () => {
},
classDetectorV2
);
registerDiagramAndDetector(
registerDiagram(
'er',
{
parser: erParser,
Expand All @@ -197,7 +183,7 @@ export const addDiagrams = () => {
},
erDetector
);
registerDiagramAndDetector(
registerDiagram(
'gantt',
{
parser: ganttParser,
Expand All @@ -207,7 +193,7 @@ export const addDiagrams = () => {
},
ganttDetector
);
registerDiagramAndDetector(
registerDiagram(
'info',
{
parser: infoParser,
Expand All @@ -217,7 +203,7 @@ export const addDiagrams = () => {
},
infoDetector
);
registerDiagramAndDetector(
registerDiagram(
'pie',
{
parser: pieParser,
Expand All @@ -227,7 +213,7 @@ export const addDiagrams = () => {
},
pieDetector
);
registerDiagramAndDetector(
registerDiagram(
'requirement',
{
parser: requirementParser,
Expand All @@ -237,7 +223,7 @@ export const addDiagrams = () => {
},
requirementDetector
);
registerDiagramAndDetector(
registerDiagram(
'sequence',
{
parser: sequenceParser,
Expand All @@ -260,7 +246,7 @@ export const addDiagrams = () => {
},
sequenceDetector
);
registerDiagramAndDetector(
registerDiagram(
'state',
{
parser: stateParser,
Expand All @@ -277,7 +263,7 @@ export const addDiagrams = () => {
},
stateDetector
);
registerDiagramAndDetector(
registerDiagram(
'stateDiagram',
{
parser: stateParser,
Expand All @@ -294,7 +280,7 @@ export const addDiagrams = () => {
},
stateDetectorV2
);
registerDiagramAndDetector(
registerDiagram(
'journey',
{
parser: journeyParser,
Expand All @@ -309,7 +295,7 @@ export const addDiagrams = () => {
journeyDetector
);

registerDiagramAndDetector(
registerDiagram(
'flowchart',
{
parser: flowParser,
Expand All @@ -329,7 +315,7 @@ export const addDiagrams = () => {
},
flowDetector
);
registerDiagramAndDetector(
registerDiagram(
'flowchart-v2',
{
parser: flowParser,
Expand All @@ -350,14 +336,9 @@ export const addDiagrams = () => {
},
flowDetectorV2
);
registerDiagramAndDetector(
registerDiagram(
'gitGraph',
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
gitGraphDetector
);
// registerDiagram(
// 'mindmap',
// { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles },
// mindmapDetector
// );
};

0 comments on commit 9eb8a1e

Please sign in to comment.