tsConversion: fix DiagramAPI

This commit is contained in:
Sidharth Vinod
2022-08-22 13:18:50 +05:30
parent c245a2da07
commit 1549eb20df
9 changed files with 121 additions and 65 deletions

View File

@@ -1433,24 +1433,6 @@ Returns **[object][5]** The siteConfig
Returns **[object][5]** The siteConfig Returns **[object][5]** The siteConfig
## setConfig
## setConfig
| Function | Description | Type | Values |
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
**Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure
keys. Any values found in conf with key found in siteConfig.secure will be replaced with the
corresponding siteConfig value.
### Parameters
- `conf` **any** The potential currentConfig
Returns **any** The currentConfig merged with the sanitized conf
## render ## render
Function that renders an svg with a graph from a chart definition. Usage example below. Function that renders an svg with a graph from a chart definition. Usage example below.
@@ -1479,6 +1461,24 @@ $(function () {
Returns **any** Returns **any**
## setConfig
## setConfig
| Function | Description | Type | Values |
| ------------- | ------------------------------------- | ----------- | --------------------------------------- |
| setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
**Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure
keys. Any values found in conf with key found in siteConfig.secure will be replaced with the
corresponding siteConfig value.
### Parameters
- `conf` **any** The potential currentConfig
Returns **any** The currentConfig merged with the sanitized conf
## getConfig ## getConfig
## getConfig ## getConfig

View File

@@ -1,5 +1,6 @@
const path = require('path'); const path = require('path');
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = { module.exports = {
testEnvironment: 'jsdom', testEnvironment: 'jsdom',
preset: 'ts-jest', preset: 'ts-jest',
@@ -11,7 +12,7 @@ module.exports = {
], ],
}, },
transformIgnorePatterns: ['/node_modules/(?!dagre-d3-renderer/lib|khroma).*\\.js'], transformIgnorePatterns: ['/node_modules/(?!dagre-d3-renderer/lib|khroma).*\\.js'],
testPathIgnorePatterns: ['/node_modules/', '.cache'], testPathIgnorePatterns: ['/node_modules/', '.cache', './cypress'],
moduleNameMapper: { moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy', '\\.(css|scss)$': 'identity-obj-proxy',
}, },

View File

@@ -41,7 +41,7 @@
"test": "yarn lint && jest src/.*", "test": "yarn lint && jest src/.*",
"test:watch": "jest --watch src", "test:watch": "jest --watch src",
"prepublishOnly": "yarn build && yarn test", "prepublishOnly": "yarn build && yarn test",
"prepare": "husky install && yarn build", "prepare": "husky install",
"pre-commit": "lint-staged" "pre-commit": "lint-staged"
}, },
"repository": { "repository": {

View File

@@ -1,6 +1,6 @@
import * as configApi from './config'; import * as configApi from './config';
import { log } from './logger'; import { log } from './logger';
import { getDiagrams } from './diagram-api/diagramAPI'; import { getDiagram } from './diagram-api/diagramAPI';
import { detectType } from './diagram-api/detectType'; import { detectType } from './diagram-api/detectType';
export class Diagram { export class Diagram {
type = 'graph'; type = 'graph';
@@ -8,28 +8,19 @@ export class Diagram {
renderer; renderer;
db; db;
constructor(public txt: string, parseError?: Function) { constructor(public txt: string, parseError?: Function) {
const diagrams = getDiagrams();
const cnf = configApi.getConfig(); const cnf = configApi.getConfig();
this.txt = txt; this.txt = txt;
this.type = detectType(txt, cnf); this.type = detectType(txt, cnf);
const diagram = getDiagram(this.type);
log.debug('Type ' + this.type); log.debug('Type ' + this.type);
// console.log('this.type', this.type, diagrams[this.type]);
// Setup diagram // Setup diagram
// @ts-ignore this.db = diagram.db;
this.db = diagrams[this.type].db;
this.db.clear?.(); this.db.clear?.();
this.renderer = diagram.renderer;
// @ts-ignore this.parser = diagram.parser;
this.renderer = diagrams[this.type].renderer;
// @ts-ignore
this.parser = diagrams[this.type].parser;
// @ts-ignore
this.parser.parser.yy = this.db; this.parser.parser.yy = this.db;
// @ts-ignore if (diagram.init) {
if (typeof diagrams[this.type].init === 'function') { diagram.init(cnf);
// @ts-ignore
diagrams[this.type].init(cnf);
log.debug('Initialized diagram ' + this.type, cnf); log.debug('Initialized diagram ' + this.type, cnf);
} }
this.txt += '\n'; this.txt += '\n';
@@ -51,7 +42,6 @@ export class Diagram {
} catch (error) { } catch (error) {
// Is this the correct way to access mermiad's parseError() // Is this the correct way to access mermiad's parseError()
// method ? (or global.mermaid.parseError()) ? // method ? (or global.mermaid.parseError()) ?
// @ts-ignore
if (parseError) { if (parseError) {
// @ts-ignore // @ts-ignore
if (error.str != undefined) { if (error.str != undefined) {
@@ -61,7 +51,6 @@ export class Diagram {
parseError(error.str, error.hash); parseError(error.str, error.hash);
} else { } else {
// assume it is just error string and pass it on // assume it is just error string and pass it on
// @ts-ignore
parseError(error); parseError(error);
} }
} else { } else {

View File

@@ -29,6 +29,7 @@ export interface MermaidConfig {
gitGraph?: GitGraphDiagramConfig; gitGraph?: GitGraphDiagramConfig;
c4?: C4DiagramConfig; c4?: C4DiagramConfig;
dompurifyConfig?: DOMPurify.Config; dompurifyConfig?: DOMPurify.Config;
wrap?: boolean;
} }
// TODO: More configs needs to be moved in here // TODO: More configs needs to be moved in here
@@ -289,6 +290,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
} }
export interface SequenceDiagramConfig extends BaseDiagramConfig { export interface SequenceDiagramConfig extends BaseDiagramConfig {
arrowMarkerAbsolute?: boolean;
hideUnusedParticipants?: boolean; hideUnusedParticipants?: boolean;
activationWidth?: number; activationWidth?: number;
diagramMarginX?: number; diagramMarginX?: number;
@@ -326,6 +328,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
} }
export interface FlowchartDiagramConfig extends BaseDiagramConfig { export interface FlowchartDiagramConfig extends BaseDiagramConfig {
arrowMarkerAbsolute?: boolean;
diagramPadding?: number; diagramPadding?: number;
htmlLabels?: boolean; htmlLabels?: boolean;
nodeSpacing?: number; nodeSpacing?: number;

View File

@@ -23,10 +23,7 @@ import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
export const addDiagrams = () => { export const addDiagrams = () => {
registerDiagram( registerDiagram(
'gitGraph', 'gitGraph',
gitGraphParser, { parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer },
gitGraphDb,
gitGraphRenderer,
undefined,
gitGraphDetector gitGraphDetector
); );
}; };

View File

@@ -0,0 +1,29 @@
import { detectType } from './detectType';
import { getDiagram, registerDiagram } from './diagramAPI';
describe('DiagramAPI', () => {
it('should return default diagrams', () => {
expect(getDiagram('sequence')).not.toBeNull();
});
it('should throw error if diagram is not defined', () => {
expect(() => getDiagram('loki')).toThrow();
});
it('should handle diagram registrations', () => {
expect(() => getDiagram('loki')).toThrow();
// TODO Q: Shouldn't this be throwing an error?
expect(detectType('loki diagram')).toBe('flowchart');
registerDiagram(
'loki',
{
db: {},
parser: {},
renderer: {},
},
(text: string) => text.includes('loki')
);
expect(getDiagram('loki')).not.toBeNull();
expect(detectType('loki diagram')).toBe('loki');
});
});

View File

@@ -1,44 +1,62 @@
// @ts-nocheck
import c4Db from '../diagrams/c4/c4Db'; import c4Db from '../diagrams/c4/c4Db';
import c4Renderer from '../diagrams/c4/c4Renderer'; import c4Renderer from '../diagrams/c4/c4Renderer';
// @ts-ignore
import c4Parser from '../diagrams/c4/parser/c4Diagram'; import c4Parser from '../diagrams/c4/parser/c4Diagram';
import classDb from '../diagrams/class/classDb'; import classDb from '../diagrams/class/classDb';
import classRenderer from '../diagrams/class/classRenderer'; import classRenderer from '../diagrams/class/classRenderer';
import classRendererV2 from '../diagrams/class/classRenderer-v2'; import classRendererV2 from '../diagrams/class/classRenderer-v2';
// @ts-ignore
import classParser from '../diagrams/class/parser/classDiagram'; import classParser from '../diagrams/class/parser/classDiagram';
import erDb from '../diagrams/er/erDb'; import erDb from '../diagrams/er/erDb';
import erRenderer from '../diagrams/er/erRenderer'; import erRenderer from '../diagrams/er/erRenderer';
// @ts-ignore
import erParser from '../diagrams/er/parser/erDiagram'; import erParser from '../diagrams/er/parser/erDiagram';
import flowDb from '../diagrams/flowchart/flowDb'; import flowDb from '../diagrams/flowchart/flowDb';
import flowRenderer from '../diagrams/flowchart/flowRenderer'; import flowRenderer from '../diagrams/flowchart/flowRenderer';
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2'; import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
// @ts-ignore
import flowParser from '../diagrams/flowchart/parser/flow'; import flowParser from '../diagrams/flowchart/parser/flow';
import ganttDb from '../diagrams/gantt/ganttDb'; import ganttDb from '../diagrams/gantt/ganttDb';
import ganttRenderer from '../diagrams/gantt/ganttRenderer'; import ganttRenderer from '../diagrams/gantt/ganttRenderer';
// @ts-ignore
import ganttParser from '../diagrams/gantt/parser/gantt'; import ganttParser from '../diagrams/gantt/parser/gantt';
import infoDb from '../diagrams/info/infoDb'; import infoDb from '../diagrams/info/infoDb';
import infoRenderer from '../diagrams/info/infoRenderer'; import infoRenderer from '../diagrams/info/infoRenderer';
// @ts-ignore
import infoParser from '../diagrams/info/parser/info'; import infoParser from '../diagrams/info/parser/info';
// @ts-ignore
import pieParser from '../diagrams/pie/parser/pie'; import pieParser from '../diagrams/pie/parser/pie';
import pieDb from '../diagrams/pie/pieDb'; import pieDb from '../diagrams/pie/pieDb';
import pieRenderer from '../diagrams/pie/pieRenderer'; import pieRenderer from '../diagrams/pie/pieRenderer';
// @ts-ignore
import requirementParser from '../diagrams/requirement/parser/requirementDiagram'; import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
import requirementDb from '../diagrams/requirement/requirementDb'; import requirementDb from '../diagrams/requirement/requirementDb';
import requirementRenderer from '../diagrams/requirement/requirementRenderer'; import requirementRenderer from '../diagrams/requirement/requirementRenderer';
// @ts-ignore
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram'; import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
import sequenceDb from '../diagrams/sequence/sequenceDb'; import sequenceDb from '../diagrams/sequence/sequenceDb';
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer'; import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
// @ts-ignore
import stateParser from '../diagrams/state/parser/stateDiagram'; import stateParser from '../diagrams/state/parser/stateDiagram';
import stateDb from '../diagrams/state/stateDb'; import stateDb from '../diagrams/state/stateDb';
import stateRenderer from '../diagrams/state/stateRenderer'; import stateRenderer from '../diagrams/state/stateRenderer';
import stateRendererV2 from '../diagrams/state/stateRenderer-v2'; import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
import journeyDb from '../diagrams/user-journey/journeyDb'; import journeyDb from '../diagrams/user-journey/journeyDb';
import journeyRenderer from '../diagrams/user-journey/journeyRenderer'; import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
// @ts-ignore
import journeyParser from '../diagrams/user-journey/parser/journey'; import journeyParser from '../diagrams/user-journey/parser/journey';
import { addDetector } from './detectType'; import { addDetector, DiagramDetector } from './detectType';
import { log } from '../logger'; import { log } from '../logger';
import { MermaidConfig } from '../config.type';
const diagrams = { export interface DiagramDefinition {
db: any;
renderer: any;
parser: any;
init?: (config: MermaidConfig) => void;
}
const diagrams: Record<string, DiagramDefinition> = {
c4: { c4: {
db: c4Db, db: c4Db,
renderer: c4Renderer, renderer: c4Renderer,
@@ -52,6 +70,9 @@ const diagrams = {
renderer: classRenderer, renderer: classRenderer,
parser: classParser, parser: classParser,
init: (cnf) => { init: (cnf) => {
if (!cnf.class) {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
classDb.clear(); classDb.clear();
}, },
@@ -61,6 +82,9 @@ const diagrams = {
renderer: classRendererV2, renderer: classRendererV2,
parser: classParser, parser: classParser,
init: (cnf) => { init: (cnf) => {
if (!cnf.class) {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
classDb.clear(); classDb.clear();
}, },
@@ -76,6 +100,9 @@ const diagrams = {
parser: flowParser, parser: flowParser,
init: (cnf) => { init: (cnf) => {
flowRenderer.setConf(cnf.flowchart); flowRenderer.setConf(cnf.flowchart);
if (!cnf.flowchart) {
cnf.flowchart = {};
}
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowDb.clear(); flowDb.clear();
flowDb.setGen('gen-1'); flowDb.setGen('gen-1');
@@ -87,6 +114,9 @@ const diagrams = {
parser: flowParser, parser: flowParser,
init: (cnf) => { init: (cnf) => {
flowRendererV2.setConf(cnf.flowchart); flowRendererV2.setConf(cnf.flowchart);
if (!cnf.flowchart) {
cnf.flowchart = {};
}
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowDb.clear(); flowDb.clear();
flowDb.setGen('gen-2'); flowDb.setGen('gen-2');
@@ -96,15 +126,7 @@ const diagrams = {
db: ganttDb, db: ganttDb,
renderer: ganttRenderer, renderer: ganttRenderer,
parser: ganttParser, parser: ganttParser,
init: (cnf) => {
ganttRenderer.setConf(cnf.gantt);
},
}, },
// git: {
// db: gitGraphAst,
// renderer: gitGraphRenderer,
// parser: gitGraphParser,
// },
info: { info: {
db: infoDb, db: infoDb,
renderer: infoRenderer, renderer: infoRenderer,
@@ -125,11 +147,12 @@ const diagrams = {
renderer: sequenceRenderer, renderer: sequenceRenderer,
parser: sequenceParser, parser: sequenceParser,
init: (cnf) => { init: (cnf) => {
if (!cnf.sequence) {
cnf.sequence = {};
}
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
if (cnf.sequenceDiagram) { if ('sequenceDiagram' in cnf) {
// backwards compatibility throw new Error(
sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram));
console.error(
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.' '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
); );
} }
@@ -142,6 +165,10 @@ const diagrams = {
renderer: stateRenderer, renderer: stateRenderer,
parser: stateParser, parser: stateParser,
init: (cnf) => { init: (cnf) => {
// TODO Q: Why is state diagram init setting cnf.class.arrowMarkerAbsolute ?
if (!cnf.class) {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
stateDb.clear(); stateDb.clear();
}, },
@@ -151,6 +178,10 @@ const diagrams = {
renderer: stateRendererV2, renderer: stateRendererV2,
parser: stateParser, parser: stateParser,
init: (cnf) => { init: (cnf) => {
// TODO Q: Why is state diagram init setting cnf.class.arrowMarkerAbsolute ?
if (!cnf.class) {
cnf.class = {};
}
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
stateDb.clear(); stateDb.clear();
}, },
@@ -165,16 +196,22 @@ const diagrams = {
}, },
}, },
}; };
// console.log(sequenceDb);
export const registerDiagram = (id, parser, db, renderer, init, detector) => { export const registerDiagram = (
id: string,
diagram: DiagramDefinition,
detector: DiagramDetector
) => {
if (diagrams[id]) { if (diagrams[id]) {
log.warn(`Diagram ${id} already registered.`); log.warn(`Diagram ${id} already registered.`);
} }
diagrams[id] = { parser, db, renderer, init }; diagrams[id] = diagram;
addDetector(id, detector); addDetector(id, detector);
}; };
export const getDiagrams = () => { export const getDiagram = (name: string): DiagramDefinition => {
// console.log('diagrams', diagrams); if (name in diagrams) {
return diagrams; return diagrams[name];
}
throw new Error(`Diagram ${name} not found.`);
}; };

View File

@@ -425,7 +425,7 @@ funs.push(setupToolTips);
* *
* @param ver * @param ver
*/ */
export const clear = function (ver) { export const clear = function (ver = 'gen-1') {
vertices = {}; vertices = {};
classes = {}; classes = {};
edges = []; edges = [];
@@ -436,7 +436,7 @@ export const clear = function (ver) {
subCount = 0; subCount = 0;
tooltips = []; tooltips = [];
firstGraphFlag = true; firstGraphFlag = true;
version = ver || 'gen-1'; version = ver;
commonClear(); commonClear();
}; };
export const setGen = (ver) => { export const setGen = (ver) => {