Merge remote-tracking branch 'MERMAID/develop' into docs/3418_auto_generated_comment_html_files
# Conflicts: # src/docs.mts
This commit is contained in:
commit
ad56a22277
|
@ -1,3 +1,5 @@
|
||||||
dist/**
|
dist/**
|
||||||
.github/**
|
.github/**
|
||||||
docs/Setup.md
|
docs/Setup.md
|
||||||
|
cypress.config.js
|
||||||
|
cypress/plugins/index.js
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
"plugin:jsdoc/recommended",
|
"plugin:jsdoc/recommended",
|
||||||
"plugin:json/recommended",
|
"plugin:json/recommended",
|
||||||
"plugin:markdown/recommended",
|
"plugin:markdown/recommended",
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
],
|
],
|
||||||
"plugins": ["@typescript-eslint", "html", "jest", "jsdoc", "json"],
|
"plugins": ["@typescript-eslint", "html", "jest", "jsdoc", "json"],
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"no-console": "error",
|
||||||
"no-prototype-builtins": "off",
|
"no-prototype-builtins": "off",
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
"jsdoc/check-indentation": "off",
|
"jsdoc/check-indentation": "off",
|
||||||
|
@ -35,6 +37,16 @@
|
||||||
"jsdoc/require-returns": "off",
|
"jsdoc/require-returns": "off",
|
||||||
"jsdoc/require-returns-description": "off",
|
"jsdoc/require-returns-description": "off",
|
||||||
"cypress/no-async-tests": "off",
|
"cypress/no-async-tests": "off",
|
||||||
|
"@typescript-eslint/ban-ts-comment": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ts-expect-error": "allow-with-description",
|
||||||
|
"ts-ignore": "allow-with-description",
|
||||||
|
"ts-nocheck": "allow-with-description",
|
||||||
|
"ts-check": "allow-with-description",
|
||||||
|
"minimumDescriptionLength": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
"json/*": ["error", "allowComments"],
|
"json/*": ["error", "allowComments"],
|
||||||
"no-empty": ["error", { "allowEmptyCatch": true }]
|
"no-empty": ["error", { "allowEmptyCatch": true }]
|
||||||
},
|
},
|
||||||
|
@ -45,6 +57,12 @@
|
||||||
"no-undef": "off",
|
"no-undef": "off",
|
||||||
"jsdoc/require-jsdoc": "off"
|
"jsdoc/require-jsdoc": "off"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["./cypress/**", "./demos/**"],
|
||||||
|
"rules": {
|
||||||
|
"no-console": "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,3 +40,18 @@ 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"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
|
|
||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
|
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
|
||||||
require('@applitools/eyes-cypress')(module);
|
require('@applitools/eyes-cypress')(module);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
// ***********************************************************
|
// ***********************************************************
|
||||||
// This example plugins/index.js can be used to load plugins
|
// This example plugins/index.js can be used to load plugins
|
||||||
//
|
//
|
||||||
|
|
|
@ -1083,7 +1083,9 @@ Enterprise_Boundary(b0, "BankBoundary0") {
|
||||||
<script>
|
<script>
|
||||||
const testLineEndings = (test, input) => {
|
const testLineEndings = (test, input) => {
|
||||||
try {
|
try {
|
||||||
mermaid.render(test, input, () => {});
|
mermaid.render(test, input, () => {
|
||||||
|
//no-op
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error in %s:\n\n%s', test, err);
|
console.error('Error in %s:\n\n%s', test, err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||||
|
|
|
@ -8,6 +8,7 @@ export class Diagram {
|
||||||
parser;
|
parser;
|
||||||
renderer;
|
renderer;
|
||||||
db;
|
db;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
constructor(public txt: string, parseError?: Function) {
|
constructor(public txt: string, parseError?: Function) {
|
||||||
const cnf = configApi.getConfig();
|
const cnf = configApi.getConfig();
|
||||||
this.txt = txt;
|
this.txt = txt;
|
||||||
|
@ -33,6 +34,7 @@ export class Diagram {
|
||||||
this.parse(this.txt, parseError);
|
this.parse(this.txt, parseError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
parse(text: string, parseError?: Function): boolean {
|
parse(text: string, parseError?: Function): boolean {
|
||||||
try {
|
try {
|
||||||
text = text + '\n';
|
text = text + '\n';
|
||||||
|
|
|
@ -19,6 +19,7 @@ let hasLoadedDiagrams = false;
|
||||||
* @param text
|
* @param text
|
||||||
* @param parseError
|
* @param parseError
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
function parse(text: string, parseError?: Function): boolean {
|
function parse(text: string, parseError?: Function): boolean {
|
||||||
if (!hasLoadedDiagrams) {
|
if (!hasLoadedDiagrams) {
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
|
|
@ -62,9 +62,9 @@ export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => {
|
||||||
siteConfig = assignWithDepth({}, defaultConfig);
|
siteConfig = assignWithDepth({}, defaultConfig);
|
||||||
siteConfig = assignWithDepth(siteConfig, conf);
|
siteConfig = assignWithDepth(siteConfig, conf);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
if (conf.theme && theme[conf.theme]) {
|
if (conf.theme && theme[conf.theme]) {
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
|
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +216,8 @@ export const addDirective = (directive: any) => {
|
||||||
* | conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
* | conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
||||||
*
|
*
|
||||||
* **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
* **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
*/
|
*/
|
||||||
export const reset = (config = siteConfig): void => {
|
export const reset = (config = siteConfig): void => {
|
||||||
// Replace current config with siteConfig
|
// Replace current config with siteConfig
|
||||||
|
|
|
@ -219,7 +219,8 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
|
||||||
padding: number;
|
padding: number;
|
||||||
maxNodeWidth: number;
|
maxNodeWidth: number;
|
||||||
}
|
}
|
||||||
export interface PieDiagramConfig extends BaseDiagramConfig {}
|
|
||||||
|
export type PieDiagramConfig = BaseDiagramConfig;
|
||||||
|
|
||||||
export interface ErDiagramConfig extends BaseDiagramConfig {
|
export interface ErDiagramConfig extends BaseDiagramConfig {
|
||||||
diagramPadding?: number;
|
diagramPadding?: number;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { registerDiagram } from './diagramAPI';
|
import { registerDiagram } from './diagramAPI';
|
||||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||||
import mindmapStyles from '../diagrams/mindmap/styles';
|
import mindmapStyles from '../diagrams/mindmap/styles';
|
||||||
|
|
||||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||||
import gitGraphStyles from '../diagrams/git/styles';
|
import gitGraphStyles from '../diagrams/git/styles';
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
import c4Db from '../diagrams/c4/c4Db';
|
import c4Db from '../diagrams/c4/c4Db';
|
||||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||||
import c4Styles from '../diagrams/c4/styles';
|
import c4Styles from '../diagrams/c4/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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';
|
||||||
import classStyles from '../diagrams/class/styles';
|
import classStyles from '../diagrams/class/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import erParser from '../diagrams/er/parser/erDiagram';
|
import erParser from '../diagrams/er/parser/erDiagram';
|
||||||
import erStyles from '../diagrams/er/styles';
|
import erStyles from '../diagrams/er/styles';
|
||||||
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';
|
||||||
import flowStyles from '../diagrams/flowchart/styles';
|
import flowStyles from '../diagrams/flowchart/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||||
import ganttStyles from '../diagrams/gantt/styles';
|
import ganttStyles from '../diagrams/gantt/styles';
|
||||||
|
|
||||||
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
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import infoParser from '../diagrams/info/parser/info';
|
import infoParser from '../diagrams/info/parser/info';
|
||||||
import infoStyles from '../diagrams/info/styles';
|
import infoStyles from '../diagrams/info/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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';
|
||||||
import pieStyles from '../diagrams/pie/styles';
|
import pieStyles from '../diagrams/pie/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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';
|
||||||
import requirementStyles from '../diagrams/requirement/styles';
|
import requirementStyles from '../diagrams/requirement/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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';
|
||||||
import sequenceStyles from '../diagrams/sequence/styles';
|
import sequenceStyles from '../diagrams/sequence/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
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';
|
||||||
|
@ -55,7 +55,7 @@ import stateStyles from '../diagrams/state/styles';
|
||||||
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';
|
||||||
import journeyStyles from '../diagrams/user-journey/styles';
|
import journeyStyles from '../diagrams/user-journey/styles';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||||
import { addDetector, DiagramDetector } from './detectType';
|
import { addDetector, DiagramDetector } from './detectType';
|
||||||
import { log as _log } from '../logger';
|
import { log as _log } from '../logger';
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
import c4Db from '../c4Db';
|
||||||
|
import c4 from './c4Diagram.jison';
|
||||||
|
import { setConfig } from '../../../config';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
securityLevel: 'strict',
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.each(['Boundary'])('parsing a C4 %s', function (macroName) {
|
||||||
|
beforeEach(function () {
|
||||||
|
c4.parser.yy = c4Db;
|
||||||
|
c4.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a C4 diagram with one Boundary correctly', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
title System Context diagram for Internet Banking System
|
||||||
|
${macroName}(b1, "BankBoundary") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
const yy = c4.parser.yy;
|
||||||
|
|
||||||
|
const boundaries = yy.getBoundarys();
|
||||||
|
expect(boundaries.length).toBe(2);
|
||||||
|
const boundary = boundaries[1];
|
||||||
|
|
||||||
|
expect(boundary).toEqual({
|
||||||
|
alias: 'b1',
|
||||||
|
label: {
|
||||||
|
text: 'BankBoundary',
|
||||||
|
},
|
||||||
|
// TODO: Why are link, and tags undefined instead of not appearing at all?
|
||||||
|
// Compare to Person where they don't show up.
|
||||||
|
link: undefined,
|
||||||
|
tags: undefined,
|
||||||
|
parentBoundary: 'global',
|
||||||
|
type: {
|
||||||
|
// TODO: Why is this `system` instead of `boundary`?
|
||||||
|
text: 'system',
|
||||||
|
},
|
||||||
|
wrap: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the alias', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(b1, "BankBoundary") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||||
|
alias: 'b1',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the label', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(b1, "BankBoundary") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: 'BankBoundary',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the type', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(b1, "", "company") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||||
|
type: { text: 'company' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a link', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(b1, $link="https://github.com/mermaidjs") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
link: 'https://github.com/mermaidjs',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse tags', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(b1, $tags="tag1,tag2") {
|
||||||
|
System(SystemAA, "Internet Banking System")
|
||||||
|
}`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
tags: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -115,80 +115,80 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||||
"C4Dynamic" return 'C4_DYNAMIC';
|
"C4Dynamic" return 'C4_DYNAMIC';
|
||||||
"C4Deployment" return 'C4_DEPLOYMENT';
|
"C4Deployment" return 'C4_DEPLOYMENT';
|
||||||
|
|
||||||
"Person_Ext" { this.begin("person_ext"); console.log('begin person_ext'); return 'PERSON_EXT';}
|
"Person_Ext" { this.begin("person_ext"); return 'PERSON_EXT';}
|
||||||
"Person" { this.begin("person"); console.log('begin person'); return 'PERSON';}
|
"Person" { this.begin("person"); return 'PERSON';}
|
||||||
"SystemQueue_Ext" { this.begin("system_ext_queue"); console.log('begin system_ext_queue'); return 'SYSTEM_EXT_QUEUE';}
|
"SystemQueue_Ext" { this.begin("system_ext_queue"); return 'SYSTEM_EXT_QUEUE';}
|
||||||
"SystemDb_Ext" { this.begin("system_ext_db"); console.log('begin system_ext_db'); return 'SYSTEM_EXT_DB';}
|
"SystemDb_Ext" { this.begin("system_ext_db"); return 'SYSTEM_EXT_DB';}
|
||||||
"System_Ext" { this.begin("system_ext"); console.log('begin system_ext'); return 'SYSTEM_EXT';}
|
"System_Ext" { this.begin("system_ext"); return 'SYSTEM_EXT';}
|
||||||
"SystemQueue" { this.begin("system_queue"); console.log('begin system_queue'); return 'SYSTEM_QUEUE';}
|
"SystemQueue" { this.begin("system_queue"); return 'SYSTEM_QUEUE';}
|
||||||
"SystemDb" { this.begin("system_db"); console.log('begin system_db'); return 'SYSTEM_DB';}
|
"SystemDb" { this.begin("system_db"); return 'SYSTEM_DB';}
|
||||||
"System" { this.begin("system"); console.log('begin system'); return 'SYSTEM';}
|
"System" { this.begin("system"); return 'SYSTEM';}
|
||||||
|
|
||||||
"Boundary" { this.begin("boundary"); console.log('begin boundary'); return 'BOUNDARY';}
|
"Boundary" { this.begin("boundary"); return 'BOUNDARY';}
|
||||||
"Enterprise_Boundary" { this.begin("enterprise_boundary"); console.log('begin enterprise_boundary'); return 'ENTERPRISE_BOUNDARY';}
|
"Enterprise_Boundary" { this.begin("enterprise_boundary"); return 'ENTERPRISE_BOUNDARY';}
|
||||||
"System_Boundary" { this.begin("system_boundary"); console.log('begin system_boundary'); return 'SYSTEM_BOUNDARY';}
|
"System_Boundary" { this.begin("system_boundary"); return 'SYSTEM_BOUNDARY';}
|
||||||
|
|
||||||
"ContainerQueue_Ext" { this.begin("container_ext_queue"); console.log('begin container_ext_queue'); return 'CONTAINER_EXT_QUEUE';}
|
"ContainerQueue_Ext" { this.begin("container_ext_queue"); return 'CONTAINER_EXT_QUEUE';}
|
||||||
"ContainerDb_Ext" { this.begin("container_ext_db"); console.log('begin container_ext_db'); return 'CONTAINER_EXT_DB';}
|
"ContainerDb_Ext" { this.begin("container_ext_db"); return 'CONTAINER_EXT_DB';}
|
||||||
"Container_Ext" { this.begin("container_ext"); console.log('begin container_ext'); return 'CONTAINER_EXT';}
|
"Container_Ext" { this.begin("container_ext"); return 'CONTAINER_EXT';}
|
||||||
"ContainerQueue" { this.begin("container_queue"); console.log('begin container_queue'); return 'CONTAINER_QUEUE';}
|
"ContainerQueue" { this.begin("container_queue"); return 'CONTAINER_QUEUE';}
|
||||||
"ContainerDb" { this.begin("container_db"); console.log('begin container_db'); return 'CONTAINER_DB';}
|
"ContainerDb" { this.begin("container_db"); return 'CONTAINER_DB';}
|
||||||
"Container" { this.begin("container"); console.log('begin container'); return 'CONTAINER';}
|
"Container" { this.begin("container"); return 'CONTAINER';}
|
||||||
|
|
||||||
"Container_Boundary" { this.begin("container_boundary"); console.log('begin container_boundary'); return 'CONTAINER_BOUNDARY';}
|
"Container_Boundary" { this.begin("container_boundary"); return 'CONTAINER_BOUNDARY';}
|
||||||
|
|
||||||
"ComponentQueue_Ext" { this.begin("component_ext_queue"); console.log('begin component_ext_queue'); return 'COMPONENT_EXT_QUEUE';}
|
"ComponentQueue_Ext" { this.begin("component_ext_queue"); return 'COMPONENT_EXT_QUEUE';}
|
||||||
"ComponentDb_Ext" { this.begin("component_ext_db"); console.log('begin component_ext_db'); return 'COMPONENT_EXT_DB';}
|
"ComponentDb_Ext" { this.begin("component_ext_db"); return 'COMPONENT_EXT_DB';}
|
||||||
"Component_Ext" { this.begin("component_ext"); console.log('begin component_ext'); return 'COMPONENT_EXT';}
|
"Component_Ext" { this.begin("component_ext"); return 'COMPONENT_EXT';}
|
||||||
"ComponentQueue" { this.begin("component_queue"); console.log('begin component_queue'); return 'COMPONENT_QUEUE';}
|
"ComponentQueue" { this.begin("component_queue"); return 'COMPONENT_QUEUE';}
|
||||||
"ComponentDb" { this.begin("component_db"); console.log('begin component_db'); return 'COMPONENT_DB';}
|
"ComponentDb" { this.begin("component_db"); return 'COMPONENT_DB';}
|
||||||
"Component" { this.begin("component"); console.log('begin component'); return 'COMPONENT';}
|
"Component" { this.begin("component"); return 'COMPONENT';}
|
||||||
|
|
||||||
"Deployment_Node" { this.begin("node"); console.log('begin node'); return 'NODE';}
|
"Deployment_Node" { this.begin("node"); return 'NODE';}
|
||||||
"Node" { this.begin("node"); console.log('begin node'); return 'NODE';}
|
"Node" { this.begin("node"); return 'NODE';}
|
||||||
"Node_L" { this.begin("node_l"); console.log('begin node_l'); return 'NODE_L';}
|
"Node_L" { this.begin("node_l"); return 'NODE_L';}
|
||||||
"Node_R" { this.begin("node_r"); console.log('begin node_r'); return 'NODE_R';}
|
"Node_R" { this.begin("node_r"); return 'NODE_R';}
|
||||||
|
|
||||||
|
|
||||||
"Rel" { this.begin("rel"); console.log('begin rel'); return 'REL';}
|
"Rel" { this.begin("rel"); return 'REL';}
|
||||||
"BiRel" { this.begin("birel"); console.log('begin birel'); return 'BIREL';}
|
"BiRel" { this.begin("birel"); return 'BIREL';}
|
||||||
"Rel_Up" { this.begin("rel_u"); console.log('begin rel_u'); return 'REL_U';}
|
"Rel_Up" { this.begin("rel_u"); return 'REL_U';}
|
||||||
"Rel_U" { this.begin("rel_u"); console.log('begin rel_u'); return 'REL_U';}
|
"Rel_U" { this.begin("rel_u"); return 'REL_U';}
|
||||||
"Rel_Down" { this.begin("rel_d"); console.log('begin rel_d'); return 'REL_D';}
|
"Rel_Down" { this.begin("rel_d"); return 'REL_D';}
|
||||||
"Rel_D" { this.begin("rel_d"); console.log('begin rel_d'); return 'REL_D';}
|
"Rel_D" { this.begin("rel_d"); return 'REL_D';}
|
||||||
"Rel_Left" { this.begin("rel_l"); console.log('begin rel_l'); return 'REL_L';}
|
"Rel_Left" { this.begin("rel_l"); return 'REL_L';}
|
||||||
"Rel_L" { this.begin("rel_l"); console.log('begin rel_l'); return 'REL_L';}
|
"Rel_L" { this.begin("rel_l"); return 'REL_L';}
|
||||||
"Rel_Right" { this.begin("rel_r"); console.log('begin rel_r'); return 'REL_R';}
|
"Rel_Right" { this.begin("rel_r"); return 'REL_R';}
|
||||||
"Rel_R" { this.begin("rel_r"); console.log('begin rel_r'); return 'REL_R';}
|
"Rel_R" { this.begin("rel_r"); return 'REL_R';}
|
||||||
"Rel_Back" { this.begin("rel_b"); console.log('begin rel_b'); return 'REL_B';}
|
"Rel_Back" { this.begin("rel_b"); return 'REL_B';}
|
||||||
"RelIndex" { this.begin("rel_index"); console.log('begin rel_index'); return 'REL_INDEX';}
|
"RelIndex" { this.begin("rel_index"); return 'REL_INDEX';}
|
||||||
|
|
||||||
"UpdateElementStyle" { this.begin("update_el_style"); console.log('begin update_el_style'); return 'UPDATE_EL_STYLE';}
|
"UpdateElementStyle" { this.begin("update_el_style"); return 'UPDATE_EL_STYLE';}
|
||||||
"UpdateRelStyle" { this.begin("update_rel_style"); console.log('begin update_rel_style'); return 'UPDATE_REL_STYLE';}
|
"UpdateRelStyle" { this.begin("update_rel_style"); return 'UPDATE_REL_STYLE';}
|
||||||
"UpdateLayoutConfig" { this.begin("update_layout_config"); console.log('begin update_layout_config'); return 'UPDATE_LAYOUT_CONFIG';}
|
"UpdateLayoutConfig" { this.begin("update_layout_config"); return 'UPDATE_LAYOUT_CONFIG';}
|
||||||
|
|
||||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config><<EOF>> return "EOF_IN_STRUCT";
|
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config><<EOF>> return "EOF_IN_STRUCT";
|
||||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { console.log('begin attribute with ATTRIBUTE_EMPTY'); this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
|
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
|
||||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { console.log('begin attribute'); this.begin("attribute"); }
|
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { this.begin("attribute"); }
|
||||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { console.log('STOP attribute'); this.popState();console.log('STOP diagram'); this.popState();}
|
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { this.popState();this.popState();}
|
||||||
|
|
||||||
<attribute>",," { console.log(',,'); return 'ATTRIBUTE_EMPTY';}
|
<attribute>",," { return 'ATTRIBUTE_EMPTY';}
|
||||||
<attribute>"," { console.log(','); }
|
<attribute>"," { }
|
||||||
<attribute>[ ]*["]["] { console.log('ATTRIBUTE_EMPTY'); return 'ATTRIBUTE_EMPTY';}
|
<attribute>[ ]*["]["] { return 'ATTRIBUTE_EMPTY';}
|
||||||
<attribute>[ ]*["] { console.log('begin string'); this.begin("string");}
|
<attribute>[ ]*["] { this.begin("string");}
|
||||||
<string>["] { console.log('STOP string'); this.popState(); }
|
<string>["] { this.popState(); }
|
||||||
<string>[^"]* { console.log('STR'); return "STR";}
|
<string>[^"]* { return "STR";}
|
||||||
|
|
||||||
<attribute>[ ]*[\$] { console.log('begin string_kv'); this.begin("string_kv");}
|
<attribute>[ ]*[\$] { this.begin("string_kv");}
|
||||||
<string_kv>[^=]* { console.log('STR_KEY'); this.begin("string_kv_key"); return "STR_KEY";}
|
<string_kv>[^=]* { this.begin("string_kv_key"); return "STR_KEY";}
|
||||||
<string_kv_key>[=][ ]*["] { console.log('begin string_kv_value'); this.popState(); this.begin("string_kv_value"); }
|
<string_kv_key>[=][ ]*["] { this.popState(); this.begin("string_kv_value"); }
|
||||||
<string_kv_value>[^"]+ { console.log('STR_VALUE'); return "STR_VALUE";}
|
<string_kv_value>[^"]+ { return "STR_VALUE";}
|
||||||
<string_kv_value>["] { console.log('STOP string_kv_value'); this.popState(); this.popState(); }
|
<string_kv_value>["] { this.popState(); this.popState(); }
|
||||||
|
|
||||||
<attribute>[^,]+ { console.log('not STR'); return "STR";}
|
<attribute>[^,]+ { return "STR";}
|
||||||
|
|
||||||
'{' { /* this.begin("lbrace"); */ console.log('begin boundary block'); return "LBRACE";}
|
'{' { /* this.begin("lbrace"); */ return "LBRACE";}
|
||||||
'}' { /* this.popState(); */ console.log('STOP boundary block'); return "RBRACE";}
|
'}' { /* this.popState(); */ return "RBRACE";}
|
||||||
|
|
||||||
[\s]+ return 'SPACE';
|
[\s]+ return 'SPACE';
|
||||||
[\n\r]+ return 'EOL';
|
[\n\r]+ return 'EOL';
|
||||||
|
@ -231,7 +231,7 @@ directive
|
||||||
;
|
;
|
||||||
|
|
||||||
openDirective
|
openDirective
|
||||||
: open_directive { console.log("open_directive: ", $1); yy.parseDirective('%%{', 'open_directive'); }
|
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
|
||||||
;
|
;
|
||||||
|
|
||||||
typeDirective
|
typeDirective
|
||||||
|
@ -239,11 +239,11 @@ typeDirective
|
||||||
;
|
;
|
||||||
|
|
||||||
argDirective
|
argDirective
|
||||||
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); console.log("arg_directive: ", $1); yy.parseDirective($1, 'arg_directive'); }
|
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
|
||||||
;
|
;
|
||||||
|
|
||||||
closeDirective
|
closeDirective
|
||||||
: close_directive { console.log("close_directive: ", $1); yy.parseDirective('}%%', 'close_directive', 'c4Context'); }
|
: close_directive { yy.parseDirective('}%%', 'close_directive', 'c4Context'); }
|
||||||
;
|
;
|
||||||
|
|
||||||
graphConfig
|
graphConfig
|
||||||
|
@ -285,13 +285,13 @@ boundaryStartStatement
|
||||||
;
|
;
|
||||||
|
|
||||||
boundaryStart
|
boundaryStart
|
||||||
: ENTERPRISE_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
: ENTERPRISE_BOUNDARY attributes {$2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||||
| SYSTEM_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
| SYSTEM_BOUNDARY attributes {$2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||||
| BOUNDARY attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
| BOUNDARY attributes {yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||||
| CONTAINER_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'CONTAINER'); yy.addContainerBoundary(...$2); $$=$2;}
|
| CONTAINER_BOUNDARY attributes {$2.splice(2, 0, 'CONTAINER'); yy.addContainerBoundary(...$2); $$=$2;}
|
||||||
| NODE attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('node', ...$2); $$=$2;}
|
| NODE attributes {yy.addDeploymentNode('node', ...$2); $$=$2;}
|
||||||
| NODE_L attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('nodeL', ...$2); $$=$2;}
|
| NODE_L attributes {yy.addDeploymentNode('nodeL', ...$2); $$=$2;}
|
||||||
| NODE_R attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('nodeR', ...$2); $$=$2;}
|
| NODE_R attributes {yy.addDeploymentNode('nodeR', ...$2); $$=$2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
boundaryStopStatement
|
boundaryStopStatement
|
||||||
|
@ -305,48 +305,48 @@ diagramStatements
|
||||||
;
|
;
|
||||||
|
|
||||||
diagramStatement
|
diagramStatement
|
||||||
: PERSON attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('person', ...$2); $$=$2;}
|
: PERSON attributes {yy.addPersonOrSystem('person', ...$2); $$=$2;}
|
||||||
| PERSON_EXT attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_person', ...$2); $$=$2;}
|
| PERSON_EXT attributes {yy.addPersonOrSystem('external_person', ...$2); $$=$2;}
|
||||||
| SYSTEM attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system', ...$2); $$=$2;}
|
| SYSTEM attributes {yy.addPersonOrSystem('system', ...$2); $$=$2;}
|
||||||
| SYSTEM_DB attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system_db', ...$2); $$=$2;}
|
| SYSTEM_DB attributes {yy.addPersonOrSystem('system_db', ...$2); $$=$2;}
|
||||||
| SYSTEM_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system_queue', ...$2); $$=$2;}
|
| SYSTEM_QUEUE attributes {yy.addPersonOrSystem('system_queue', ...$2); $$=$2;}
|
||||||
| SYSTEM_EXT attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system', ...$2); $$=$2;}
|
| SYSTEM_EXT attributes {yy.addPersonOrSystem('external_system', ...$2); $$=$2;}
|
||||||
| SYSTEM_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system_db', ...$2); $$=$2;}
|
| SYSTEM_EXT_DB attributes {yy.addPersonOrSystem('external_system_db', ...$2); $$=$2;}
|
||||||
| SYSTEM_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
|
| SYSTEM_EXT_QUEUE attributes {yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
|
||||||
| CONTAINER attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container', ...$2); $$=$2;}
|
| CONTAINER attributes {yy.addContainer('container', ...$2); $$=$2;}
|
||||||
| CONTAINER_DB attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container_db', ...$2); $$=$2;}
|
| CONTAINER_DB attributes {yy.addContainer('container_db', ...$2); $$=$2;}
|
||||||
| CONTAINER_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container_queue', ...$2); $$=$2;}
|
| CONTAINER_QUEUE attributes {yy.addContainer('container_queue', ...$2); $$=$2;}
|
||||||
| CONTAINER_EXT attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container', ...$2); $$=$2;}
|
| CONTAINER_EXT attributes {yy.addContainer('external_container', ...$2); $$=$2;}
|
||||||
| CONTAINER_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container_db', ...$2); $$=$2;}
|
| CONTAINER_EXT_DB attributes {yy.addContainer('external_container_db', ...$2); $$=$2;}
|
||||||
| CONTAINER_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container_queue', ...$2); $$=$2;}
|
| CONTAINER_EXT_QUEUE attributes {yy.addContainer('external_container_queue', ...$2); $$=$2;}
|
||||||
| COMPONENT attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component', ...$2); $$=$2;}
|
| COMPONENT attributes {yy.addComponent('component', ...$2); $$=$2;}
|
||||||
| COMPONENT_DB attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component_db', ...$2); $$=$2;}
|
| COMPONENT_DB attributes {yy.addComponent('component_db', ...$2); $$=$2;}
|
||||||
| COMPONENT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component_queue', ...$2); $$=$2;}
|
| COMPONENT_QUEUE attributes {yy.addComponent('component_queue', ...$2); $$=$2;}
|
||||||
| COMPONENT_EXT attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component', ...$2); $$=$2;}
|
| COMPONENT_EXT attributes {yy.addComponent('external_component', ...$2); $$=$2;}
|
||||||
| COMPONENT_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component_db', ...$2); $$=$2;}
|
| COMPONENT_EXT_DB attributes {yy.addComponent('external_component_db', ...$2); $$=$2;}
|
||||||
| COMPONENT_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component_queue', ...$2); $$=$2;}
|
| COMPONENT_EXT_QUEUE attributes {yy.addComponent('external_component_queue', ...$2); $$=$2;}
|
||||||
| boundaryStatement
|
| boundaryStatement
|
||||||
| REL attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel', ...$2); $$=$2;}
|
| REL attributes {yy.addRel('rel', ...$2); $$=$2;}
|
||||||
| BIREL attributes {console.log($1,JSON.stringify($2)); yy.addRel('birel', ...$2); $$=$2;}
|
| BIREL attributes {yy.addRel('birel', ...$2); $$=$2;}
|
||||||
| REL_U attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_u', ...$2); $$=$2;}
|
| REL_U attributes {yy.addRel('rel_u', ...$2); $$=$2;}
|
||||||
| REL_D attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_d', ...$2); $$=$2;}
|
| REL_D attributes {yy.addRel('rel_d', ...$2); $$=$2;}
|
||||||
| REL_L attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_l', ...$2); $$=$2;}
|
| REL_L attributes {yy.addRel('rel_l', ...$2); $$=$2;}
|
||||||
| REL_R attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_r', ...$2); $$=$2;}
|
| REL_R attributes {yy.addRel('rel_r', ...$2); $$=$2;}
|
||||||
| REL_B attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_b', ...$2); $$=$2;}
|
| REL_B attributes {yy.addRel('rel_b', ...$2); $$=$2;}
|
||||||
| REL_INDEX attributes {console.log($1,JSON.stringify($2)); $2.splice(0, 1); yy.addRel('rel', ...$2); $$=$2;}
|
| REL_INDEX attributes {$2.splice(0, 1); yy.addRel('rel', ...$2); $$=$2;}
|
||||||
| UPDATE_EL_STYLE attributes {console.log($1,JSON.stringify($2)); yy.updateElStyle('update_el_style', ...$2); $$=$2;}
|
| UPDATE_EL_STYLE attributes {yy.updateElStyle('update_el_style', ...$2); $$=$2;}
|
||||||
| UPDATE_REL_STYLE attributes {console.log($1,JSON.stringify($2)); yy.updateRelStyle('update_rel_style', ...$2); $$=$2;}
|
| UPDATE_REL_STYLE attributes {yy.updateRelStyle('update_rel_style', ...$2); $$=$2;}
|
||||||
| UPDATE_LAYOUT_CONFIG attributes {console.log($1,JSON.stringify($2)); yy.updateLayoutConfig('update_layout_config', ...$2); $$=$2;}
|
| UPDATE_LAYOUT_CONFIG attributes {yy.updateLayoutConfig('update_layout_config', ...$2); $$=$2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
attributes
|
attributes
|
||||||
: attribute { console.log('PUSH ATTRIBUTE: ', $1); $$ = [$1]; }
|
: attribute { $$ = [$1]; }
|
||||||
| attribute attributes { console.log('PUSH ATTRIBUTE: ', $1); $2.unshift($1); $$=$2;}
|
| attribute attributes { $2.unshift($1); $$=$2;}
|
||||||
;
|
;
|
||||||
|
|
||||||
attribute
|
attribute
|
||||||
: STR { $$ = $1.trim(); }
|
: STR { $$ = $1.trim(); }
|
||||||
| STR_KEY STR_VALUE { console.log('kv: ', $1, $2); let kv={}; kv[$1.trim()]=$2.trim(); $$=kv; }
|
| STR_KEY STR_VALUE { let kv={}; kv[$1.trim()]=$2.trim(); $$=kv; }
|
||||||
| ATTRIBUTE { $$ = $1.trim(); }
|
| ATTRIBUTE { $$ = $1.trim(); }
|
||||||
| ATTRIBUTE_EMPTY { $$ = ""; }
|
| ATTRIBUTE_EMPTY { $$ = ""; }
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,49 +1,20 @@
|
||||||
import flowDb from '../c4Db';
|
import c4Db from '../c4Db';
|
||||||
import flow from './c4Diagram.jison';
|
import c4 from './c4Diagram.jison';
|
||||||
import { setConfig } from '../../../config';
|
import { setConfig } from '../../../config';
|
||||||
|
|
||||||
setConfig({
|
setConfig({
|
||||||
securityLevel: 'strict',
|
securityLevel: 'strict',
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('parsing a flow chart', function () {
|
describe('parsing a C4 diagram', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
flow.parser.yy = flowDb;
|
c4.parser.yy = c4Db;
|
||||||
flow.parser.yy.clear();
|
c4.parser.yy.clear();
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse a C4 diagram with one Person correctly', function () {
|
|
||||||
flow.parser.parse(`C4Context
|
|
||||||
title System Context diagram for Internet Banking System
|
|
||||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
|
||||||
|
|
||||||
const yy = flow.parser.yy;
|
|
||||||
expect(yy.getC4Type()).toBe('C4Context');
|
|
||||||
expect(yy.getTitle()).toBe('System Context diagram for Internet Banking System');
|
|
||||||
|
|
||||||
const shapes = yy.getC4ShapeArray();
|
|
||||||
expect(shapes.length).toBe(1);
|
|
||||||
const onlyShape = shapes[0];
|
|
||||||
|
|
||||||
expect(onlyShape).toEqual({
|
|
||||||
alias: 'customerA',
|
|
||||||
descr: {
|
|
||||||
text: 'A customer of the bank, with personal bank accounts.',
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
text: 'Banking Customer A',
|
|
||||||
},
|
|
||||||
parentBoundary: 'global',
|
|
||||||
typeC4Shape: {
|
|
||||||
text: 'person',
|
|
||||||
},
|
|
||||||
wrap: false,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a trailing whitespaces after statements', function () {
|
it('should handle a trailing whitespaces after statements', function () {
|
||||||
const whitespace = ' ';
|
const whitespace = ' ';
|
||||||
const rendered = flow.parser.parse(`C4Context${whitespace}
|
const rendered = c4.parser.parse(`C4Context${whitespace}
|
||||||
title System Context diagram for Internet Banking System${whitespace}
|
title System Context diagram for Internet Banking System${whitespace}
|
||||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")${whitespace}`);
|
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")${whitespace}`);
|
||||||
|
|
||||||
|
@ -51,11 +22,11 @@ Person(customerA, "Banking Customer A", "A customer of the bank, with personal b
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle parameter names that are keywords', function () {
|
it('should handle parameter names that are keywords', function () {
|
||||||
flow.parser.parse(`C4Context
|
c4.parser.parse(`C4Context
|
||||||
title title
|
title title
|
||||||
Person(Person, "Person", "Person")`);
|
Person(Person, "Person", "Person")`);
|
||||||
|
|
||||||
const yy = flow.parser.yy;
|
const yy = c4.parser.yy;
|
||||||
expect(yy.getTitle()).toBe('title');
|
expect(yy.getTitle()).toBe('title');
|
||||||
|
|
||||||
const shapes = yy.getC4ShapeArray();
|
const shapes = yy.getC4ShapeArray();
|
||||||
|
@ -68,10 +39,10 @@ Person(Person, "Person", "Person")`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow default in the parameters', function () {
|
it('should allow default in the parameters', function () {
|
||||||
flow.parser.parse(`C4Context
|
c4.parser.parse(`C4Context
|
||||||
Person(default, "default", "default")`);
|
Person(default, "default", "default")`);
|
||||||
|
|
||||||
const yy = flow.parser.yy;
|
const yy = c4.parser.yy;
|
||||||
|
|
||||||
const shapes = yy.getC4ShapeArray();
|
const shapes = yy.getC4ShapeArray();
|
||||||
expect(shapes.length).toBe(1);
|
expect(shapes.length).toBe(1);
|
|
@ -0,0 +1,111 @@
|
||||||
|
import c4Db from '../c4Db';
|
||||||
|
import c4 from './c4Diagram.jison';
|
||||||
|
import { setConfig } from '../../../config';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
securityLevel: 'strict',
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parsing a C4 Person', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
c4.parser.yy = c4Db;
|
||||||
|
c4.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a C4 diagram with one Person correctly', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
title System Context diagram for Internet Banking System
|
||||||
|
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
||||||
|
|
||||||
|
const yy = c4.parser.yy;
|
||||||
|
|
||||||
|
const shapes = yy.getC4ShapeArray();
|
||||||
|
expect(shapes.length).toBe(1);
|
||||||
|
const onlyShape = shapes[0];
|
||||||
|
|
||||||
|
expect(onlyShape).toEqual({
|
||||||
|
alias: 'customerA',
|
||||||
|
descr: {
|
||||||
|
text: 'A customer of the bank, with personal bank accounts.',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
text: 'Banking Customer A',
|
||||||
|
},
|
||||||
|
parentBoundary: 'global',
|
||||||
|
typeC4Shape: {
|
||||||
|
text: 'person',
|
||||||
|
},
|
||||||
|
wrap: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the alias', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, "Banking Customer A")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
alias: 'customerA',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the label', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, "Banking Customer A")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: 'Banking Customer A',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the description', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, "", "A customer of the bank, with personal bank accounts.")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
descr: {
|
||||||
|
text: 'A customer of the bank, with personal bank accounts.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a sprite', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, $sprite="users")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
sprite: 'users',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a link', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, $link="https://github.com/mermaidjs")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
link: 'https://github.com/mermaidjs',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse tags', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person(customerA, $tags="tag1,tag2")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
tags: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,116 @@
|
||||||
|
import c4Db from '../c4Db';
|
||||||
|
import c4 from './c4Diagram.jison';
|
||||||
|
import { setConfig } from '../../../config';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
securityLevel: 'strict',
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parsing a C4 Person_Ext', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
c4.parser.yy = c4Db;
|
||||||
|
c4.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a C4 diagram with one Person_Ext correctly', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
title System Context diagram for Internet Banking System
|
||||||
|
Person_Ext(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
||||||
|
|
||||||
|
const yy = c4.parser.yy;
|
||||||
|
|
||||||
|
const shapes = yy.getC4ShapeArray();
|
||||||
|
expect(shapes.length).toBe(1);
|
||||||
|
const onlyShape = shapes[0];
|
||||||
|
|
||||||
|
expect(onlyShape).toEqual({
|
||||||
|
alias: 'customerA',
|
||||||
|
descr: {
|
||||||
|
text: 'A customer of the bank, with personal bank accounts.',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
text: 'Banking Customer A',
|
||||||
|
},
|
||||||
|
// TODO: Why are link, sprite, and tags undefined instead of not appearing at all?
|
||||||
|
// Compare to Person where they don't show up.
|
||||||
|
link: undefined,
|
||||||
|
sprite: undefined,
|
||||||
|
tags: undefined,
|
||||||
|
parentBoundary: 'global',
|
||||||
|
typeC4Shape: {
|
||||||
|
text: 'external_person',
|
||||||
|
},
|
||||||
|
wrap: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the alias', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, "Banking Customer A")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
alias: 'customerA',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the label', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, "Banking Customer A")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: 'Banking Customer A',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the description', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, "", "A customer of the bank, with personal bank accounts.")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
descr: {
|
||||||
|
text: 'A customer of the bank, with personal bank accounts.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a sprite', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, $sprite="users")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
sprite: 'users',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a link', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, $link="https://github.com/mermaidjs")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
link: 'https://github.com/mermaidjs',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse tags', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
Person_Ext(customerA, $tags="tag1,tag2")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
tags: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,123 @@
|
||||||
|
import c4Db from '../c4Db';
|
||||||
|
import c4 from './c4Diagram.jison';
|
||||||
|
import { setConfig } from '../../../config';
|
||||||
|
|
||||||
|
setConfig({
|
||||||
|
securityLevel: 'strict',
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.each([
|
||||||
|
['System', 'system'],
|
||||||
|
['SystemDb', 'system_db'],
|
||||||
|
['SystemQueue', 'system_queue'],
|
||||||
|
['System_Ext', 'external_system'],
|
||||||
|
['SystemDb_Ext', 'external_system_db'],
|
||||||
|
['SystemQueue_Ext', 'external_system_queue'],
|
||||||
|
])('parsing a C4 %s', function (macroName, elementName) {
|
||||||
|
beforeEach(function () {
|
||||||
|
c4.parser.yy = c4Db;
|
||||||
|
c4.parser.yy.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a C4 diagram with one System correctly', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
title System Context diagram for Internet Banking System
|
||||||
|
${macroName}(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")`);
|
||||||
|
|
||||||
|
const yy = c4.parser.yy;
|
||||||
|
|
||||||
|
const shapes = yy.getC4ShapeArray();
|
||||||
|
expect(shapes.length).toBe(1);
|
||||||
|
const onlyShape = shapes[0];
|
||||||
|
|
||||||
|
expect(onlyShape).toEqual({
|
||||||
|
alias: 'SystemAA',
|
||||||
|
descr: {
|
||||||
|
text: 'Allows customers to view information about their bank accounts, and make payments.',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
text: 'Internet Banking System',
|
||||||
|
},
|
||||||
|
// TODO: Why are link, sprite, and tags undefined instead of not appearing at all?
|
||||||
|
// Compare to Person where they don't show up.
|
||||||
|
link: undefined,
|
||||||
|
sprite: undefined,
|
||||||
|
tags: undefined,
|
||||||
|
parentBoundary: 'global',
|
||||||
|
typeC4Shape: {
|
||||||
|
text: elementName,
|
||||||
|
},
|
||||||
|
wrap: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the alias', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, "Internet Banking System")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
alias: 'SystemAA',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the label', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, "Internet Banking System")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: 'Internet Banking System',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse the description', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, "", "Allows customers to view information about their bank accounts, and make payments.")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
descr: {
|
||||||
|
text: 'Allows customers to view information about their bank accounts, and make payments.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a sprite', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, $sprite="users")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
sprite: 'users',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse a link', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, $link="https://github.com/mermaidjs")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
link: 'https://github.com/mermaidjs',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse tags', function () {
|
||||||
|
c4.parser.parse(`C4Context
|
||||||
|
${macroName}(SystemAA, $tags="tag1,tag2")`);
|
||||||
|
|
||||||
|
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||||
|
label: {
|
||||||
|
text: {
|
||||||
|
tags: 'tag1,tag2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
import { LALRGenerator } from 'jison';
|
import { LALRGenerator } from 'jison';
|
||||||
|
|
|
@ -550,8 +550,6 @@ describe('when parsing a gitGraph', function () {
|
||||||
testBranch3Merge,
|
testBranch3Merge,
|
||||||
] = Object.values(commits);
|
] = Object.values(commits);
|
||||||
|
|
||||||
console.log(Object.keys(commits));
|
|
||||||
|
|
||||||
expect(mainCommit.branch).toBe('main');
|
expect(mainCommit.branch).toBe('main');
|
||||||
expect(mainCommit.parents).toStrictEqual([]);
|
expect(mainCommit.parents).toStrictEqual([]);
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,9 @@ export const getCommits = () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export const clear = () => {};
|
export const clear = () => {
|
||||||
|
//no-op
|
||||||
|
};
|
||||||
export const getBranchesAsObjArray = () => [
|
export const getBranchesAsObjArray = () => [
|
||||||
{
|
{
|
||||||
name: 'master',
|
name: 'master',
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
|
import { parser } from './parser/info';
|
||||||
|
import infoDb from './infoDb';
|
||||||
describe('when parsing an info graph it', function () {
|
describe('when parsing an info graph it', function () {
|
||||||
var ex;
|
let ex;
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
ex = require('./parser/info').parser;
|
ex = parser;
|
||||||
ex.yy = require('./infoDb');
|
ex.yy = infoDb;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle an info definition', function () {
|
it('should handle an info definition', function () {
|
||||||
var str = `info
|
let str = `info
|
||||||
showInfo`;
|
showInfo`;
|
||||||
|
|
||||||
ex.parse(str);
|
ex.parse(str);
|
||||||
|
|
|
@ -49,7 +49,6 @@ export const draw = (text, id, version, diagObj) => {
|
||||||
svg.attr('width', 400);
|
svg.attr('width', 400);
|
||||||
// svg.attr('viewBox', '0 0 300 150');
|
// svg.attr('viewBox', '0 0 300 150');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
|
||||||
log.error('Error while rendering info diagram');
|
log.error('Error while rendering info diagram');
|
||||||
log.error(e.message);
|
log.error(e.message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
import { parser as mindmap } from './parser/mindmap';
|
||||||
import * as mindmapDB from './mindmapDb';
|
import * as mindmapDB from './mindmapDb';
|
||||||
import { setLogLevel } from '../../logger';
|
import { setLogLevel } from '../../logger';
|
||||||
|
|
||||||
describe('when parsing a mindmap ', function () {
|
describe('when parsing a mindmap ', function () {
|
||||||
let mindmap;
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mindmap = require('./parser/mindmap').parser;
|
mindmap.yy = mindmapDB;
|
||||||
mindmap.yy = require('./mindmapDb');
|
|
||||||
mindmap.yy.clear();
|
mindmap.yy.clear();
|
||||||
setLogLevel('trace');
|
setLogLevel('trace');
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,6 +96,7 @@ export const bounds = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateBounds: function (startx, starty, stopx, stopy) {
|
updateBounds: function (startx, starty, stopx, stopy) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||||
const _self = this;
|
const _self = this;
|
||||||
let cnt = 0;
|
let cnt = 0;
|
||||||
/** @param {any} type */
|
/** @param {any} type */
|
||||||
|
@ -653,7 +654,7 @@ export const draw = function (_text, id, _version, diagObj) {
|
||||||
// Draw the messages/signals
|
// Draw the messages/signals
|
||||||
let sequenceIndex = 1;
|
let sequenceIndex = 1;
|
||||||
let sequenceIndexStep = 1;
|
let sequenceIndexStep = 1;
|
||||||
let messagesToDraw = Array();
|
let messagesToDraw = [];
|
||||||
messages.forEach(function (msg) {
|
messages.forEach(function (msg) {
|
||||||
let loopModel, noteModel, msgModel;
|
let loopModel, noteModel, msgModel;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const svgDraw = require('./svgDraw').default;
|
import svgDraw from './svgDraw';
|
||||||
const { MockD3 } = require('d3');
|
import { MockD3 } from 'd3';
|
||||||
|
|
||||||
describe('svgDraw', function () {
|
describe('svgDraw', function () {
|
||||||
describe('drawRect', function () {
|
describe('drawRect', function () {
|
||||||
|
|
|
@ -13,7 +13,9 @@ let conf;
|
||||||
|
|
||||||
const transformationLog = {};
|
const transformationLog = {};
|
||||||
|
|
||||||
export const setConf = function () {};
|
export const setConf = function () {
|
||||||
|
//no-op
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup arrow head and define the marker. The result is appended to the svg.
|
* Setup arrow head and define the marker. The result is appended to the svg.
|
||||||
|
|
|
@ -151,6 +151,7 @@ export const bounds = {
|
||||||
},
|
},
|
||||||
updateBounds: function (startx, starty, stopx, stopy) {
|
updateBounds: function (startx, starty, stopx, stopy) {
|
||||||
const conf = getConfig().journey;
|
const conf = getConfig().journey;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||||
const _self = this;
|
const _self = this;
|
||||||
let cnt = 0;
|
let cnt = 0;
|
||||||
/** @param {any} type */
|
/** @param {any} type */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
let interactionFunctions: (() => {})[] = [];
|
let interactionFunctions: (() => void)[] = [];
|
||||||
export const addFunction = (func: () => {}) => {
|
export const addFunction = (func: () => void) => {
|
||||||
interactionFunctions.push(func);
|
interactionFunctions.push(func);
|
||||||
};
|
};
|
||||||
export const attachFunctions = () => {
|
export const attachFunctions = () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const { Generator } = require('jison');
|
const { Generator } = require('jison');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||||
|
/* eslint-disable no-console */
|
||||||
import moment from 'moment-mini';
|
import moment from 'moment-mini';
|
||||||
|
|
||||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
||||||
|
|
|
@ -14,7 +14,8 @@ import { isDetailedError } from './utils';
|
||||||
* Function that goes through the document to find the chart definitions in there and render them.
|
* Function that goes through the document to find the chart definitions in there and render them.
|
||||||
*
|
*
|
||||||
* The function tags the processed attributes with the attribute data-processed and ignores found
|
* The function tags the processed attributes with the attribute data-processed and ignores found
|
||||||
* elements with the attribute already set. This way the init function can be triggered several times.
|
* elements with the attribute already set. This way the init function can be triggered several
|
||||||
|
* times.
|
||||||
*
|
*
|
||||||
* Optionally, `init` can accept in the second argument one of the following:
|
* Optionally, `init` can accept in the second argument one of the following:
|
||||||
*
|
*
|
||||||
|
@ -39,6 +40,7 @@ const init = function (
|
||||||
config?: MermaidConfig,
|
config?: MermaidConfig,
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
callback?: Function
|
callback?: Function
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
@ -58,13 +60,14 @@ const initThrowsErrors = function (
|
||||||
config?: MermaidConfig,
|
config?: MermaidConfig,
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
callback?: Function
|
callback?: Function
|
||||||
) {
|
) {
|
||||||
const conf = mermaidAPI.getConfig();
|
const conf = mermaidAPI.getConfig();
|
||||||
// console.log('Starting rendering diagrams (init) - mermaid.init', conf);
|
// console.log('Starting rendering diagrams (init) - mermaid.init', conf);
|
||||||
if (config) {
|
if (config) {
|
||||||
// This is a legacy way of setting config. It is not documented and should be removed in the future.
|
// This is a legacy way of setting config. It is not documented and should be removed in the future.
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
mermaid.sequenceConfig = config;
|
mermaid.sequenceConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +134,7 @@ const initThrowsErrors = function (
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn('Catching Error (bootstrap)', error);
|
log.warn('Catching Error (bootstrap)', error);
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
// TODO: We should be throwing an error object.
|
// TODO: We should be throwing an error object.
|
||||||
throw { error, message: error.str };
|
throw { error, message: error.str };
|
||||||
}
|
}
|
||||||
|
@ -144,7 +147,8 @@ const initialize = function (config: MermaidConfig) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ##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 () {
|
||||||
if (mermaid.startOnLoad) {
|
if (mermaid.startOnLoad) {
|
||||||
|
@ -187,6 +191,7 @@ const parse = (txt: string) => {
|
||||||
const mermaid: {
|
const mermaid: {
|
||||||
startOnLoad: boolean;
|
startOnLoad: boolean;
|
||||||
diagrams: any;
|
diagrams: any;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
parseError?: Function;
|
parseError?: Function;
|
||||||
mermaidAPI: typeof mermaidAPI;
|
mermaidAPI: typeof mermaidAPI;
|
||||||
parse: typeof parse;
|
parse: typeof parse;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import { compile, serialize, stringify } from 'stylis';
|
import { compile, serialize, stringify } from 'stylis';
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import pkg from '../package.json';
|
import pkg from '../package.json';
|
||||||
import * as configApi from './config';
|
import * as configApi from './config';
|
||||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||||
|
@ -38,6 +38,11 @@ import { evaluate } from './diagrams/common/common';
|
||||||
|
|
||||||
let hasLoadedDiagrams = false;
|
let hasLoadedDiagrams = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param text
|
||||||
|
* @param parseError
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
function parse(text: string, parseError?: Function): boolean {
|
function parse(text: string, parseError?: Function): boolean {
|
||||||
if (!hasLoadedDiagrams) {
|
if (!hasLoadedDiagrams) {
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
|
@ -126,7 +131,7 @@ const render = function (
|
||||||
directiveSanitizer(graphInit);
|
directiveSanitizer(graphInit);
|
||||||
configApi.addDirective(graphInit);
|
configApi.addDirective(graphInit);
|
||||||
}
|
}
|
||||||
let cnf = configApi.getConfig();
|
const cnf = configApi.getConfig();
|
||||||
|
|
||||||
log.debug(cnf);
|
log.debug(cnf);
|
||||||
|
|
||||||
|
@ -319,8 +324,8 @@ const render = function (
|
||||||
svgCode = svgCode.replace(/<br>/g, '<br/>');
|
svgCode = svgCode.replace(/<br>/g, '<br/>');
|
||||||
|
|
||||||
if (cnf.securityLevel === 'sandbox') {
|
if (cnf.securityLevel === 'sandbox') {
|
||||||
let svgEl = root.select('#d' + id + ' svg').node();
|
const svgEl = root.select('#d' + id + ' svg').node();
|
||||||
let width = '100%';
|
const width = '100%';
|
||||||
let height = '100%';
|
let height = '100%';
|
||||||
if (svgEl) {
|
if (svgEl) {
|
||||||
height = svgEl.viewBox.baseVal.height + 'px';
|
height = svgEl.viewBox.baseVal.height + 'px';
|
||||||
|
@ -397,7 +402,7 @@ const parseDirective = function (p: any, statement: string, context: string, typ
|
||||||
log.error(
|
log.error(
|
||||||
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
||||||
);
|
);
|
||||||
// @ts-ignore
|
// @ts-ignore: TODO Fix ts errors
|
||||||
log.error(error.message);
|
log.error(error.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { FlowChartStyleOptions } from './diagrams/flowchart/styles';
|
||||||
import { log } from './logger';
|
import { log } from './logger';
|
||||||
|
|
||||||
// TODO @knut: Inject from registerDiagram.
|
// TODO @knut: Inject from registerDiagram.
|
||||||
const themes = {
|
const themes: Record<string, any> = {
|
||||||
flowchart,
|
flowchart,
|
||||||
'flowchart-v2': flowchart,
|
'flowchart-v2': flowchart,
|
||||||
sequence,
|
sequence,
|
||||||
|
@ -45,7 +45,7 @@ const getStyles = (
|
||||||
lineColor: string;
|
lineColor: string;
|
||||||
} & FlowChartStyleOptions
|
} & FlowChartStyleOptions
|
||||||
) => {
|
) => {
|
||||||
let diagramStyles: string = '';
|
let diagramStyles = '';
|
||||||
if (type in themes && themes[type as keyof typeof themes]) {
|
if (type in themes && themes[type as keyof typeof themes]) {
|
||||||
diagramStyles = themes[type as keyof typeof themes](options);
|
diagramStyles = themes[type as keyof typeof themes](options);
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,8 +103,7 @@ const getStyles = (
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addStylesForDiagram = (type: string, diagramTheme: any) => {
|
export const addStylesForDiagram = (type: string, diagramTheme: unknown): void => {
|
||||||
// @ts-ignore
|
|
||||||
themes[type] = diagramTheme;
|
themes[type] = diagramTheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
96
src/utils.ts
96
src/utils.ts
|
@ -1,4 +1,4 @@
|
||||||
// @ts-nocheck
|
// @ts-nocheck : TODO Fix ts errors
|
||||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||||
import {
|
import {
|
||||||
curveBasis,
|
curveBasis,
|
||||||
|
@ -43,18 +43,20 @@ const anyComment = /\s*%%.*\n/gm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function detectInit Detects the init config object from the text
|
* @function detectInit Detects the init config object from the text
|
||||||
*
|
|
||||||
* @param config
|
* @param config
|
||||||
|
* @param config
|
||||||
|
*
|
||||||
* ```mermaid
|
* ```mermaid
|
||||||
|
*
|
||||||
* %%{init: {"theme": "debug", "logLevel": 1 }}%%
|
* %%{init: {"theme": "debug", "logLevel": 1 }}%%
|
||||||
* graph LR
|
* graph LR
|
||||||
* a-->b
|
* a-->b
|
||||||
* b-->c
|
* b-->c
|
||||||
* c-->d
|
* c-->d
|
||||||
* d-->e
|
* d-->e
|
||||||
* e-->f
|
* e-->f
|
||||||
* f-->g
|
* f-->g
|
||||||
* g-->h
|
* g-->h
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Or
|
* Or
|
||||||
|
@ -75,11 +77,11 @@ const anyComment = /\s*%%.*\n/gm;
|
||||||
* @returns {object} The json object representing the init passed to mermaid.initialize()
|
* @returns {object} The json object representing the init passed to mermaid.initialize()
|
||||||
*/
|
*/
|
||||||
export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig {
|
export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig {
|
||||||
let inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
||||||
let results = {};
|
let results = {};
|
||||||
|
|
||||||
if (Array.isArray(inits)) {
|
if (Array.isArray(inits)) {
|
||||||
let args = inits.map((init) => init.args);
|
const args = inits.map((init) => init.args);
|
||||||
directiveSanitizer(args);
|
directiveSanitizer(args);
|
||||||
|
|
||||||
results = assignWithDepth(results, [...args]);
|
results = assignWithDepth(results, [...args]);
|
||||||
|
@ -134,8 +136,8 @@ export const detectDirective = function (text, type = null) {
|
||||||
log.debug(
|
log.debug(
|
||||||
`Detecting diagram directive${type !== null ? ' type:' + type : ''} based on the text:${text}`
|
`Detecting diagram directive${type !== null ? ' type:' + type : ''} based on the text:${text}`
|
||||||
);
|
);
|
||||||
let match,
|
let match;
|
||||||
result = [];
|
const result = [];
|
||||||
while ((match = directive.exec(text)) !== null) {
|
while ((match = directive.exec(text)) !== null) {
|
||||||
// This is necessary to avoid infinite loops with zero-width matches
|
// This is necessary to avoid infinite loops with zero-width matches
|
||||||
if (match.index === directive.lastIndex) {
|
if (match.index === directive.lastIndex) {
|
||||||
|
@ -146,8 +148,8 @@ export const detectDirective = function (text, type = null) {
|
||||||
(type && match[1] && match[1].match(type)) ||
|
(type && match[1] && match[1].match(type)) ||
|
||||||
(type && match[2] && match[2].match(type))
|
(type && match[2] && match[2].match(type))
|
||||||
) {
|
) {
|
||||||
let type = match[1] ? match[1] : match[2];
|
const type = match[1] ? match[1] : match[2];
|
||||||
let args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
const args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
||||||
result.push({ type, args });
|
result.push({ type, args });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,13 +175,13 @@ export const detectDirective = function (text, type = null) {
|
||||||
* @returns {Function} An optimized caching function
|
* @returns {Function} An optimized caching function
|
||||||
*/
|
*/
|
||||||
const memoize = (fn, resolver) => {
|
const memoize = (fn, resolver) => {
|
||||||
let cache = {};
|
const cache = {};
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
let n = resolver ? resolver.apply(this, args) : args[0];
|
const n = resolver ? resolver.apply(this, args) : args[0];
|
||||||
if (n in cache) {
|
if (n in cache) {
|
||||||
return cache[n];
|
return cache[n];
|
||||||
} else {
|
} else {
|
||||||
let result = fn(...args);
|
const result = fn(...args);
|
||||||
cache[n] = result;
|
cache[n] = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -222,7 +224,7 @@ export const interpolateToCurve = (interpolate, defaultCurve) => {
|
||||||
* @returns {string | undefined} The formatted URL
|
* @returns {string | undefined} The formatted URL
|
||||||
*/
|
*/
|
||||||
export const formatUrl = (linkStr, config) => {
|
export const formatUrl = (linkStr, config) => {
|
||||||
let url = linkStr.trim();
|
const url = linkStr.trim();
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
if (config.securityLevel !== 'loose') {
|
if (config.securityLevel !== 'loose') {
|
||||||
|
@ -365,10 +367,10 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition)
|
||||||
prevPoint = point;
|
prevPoint = point;
|
||||||
});
|
});
|
||||||
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
||||||
let d = isRelationTypePresent ? 10 : 5;
|
const d = isRelationTypePresent ? 10 : 5;
|
||||||
//Calculate Angle for x and y axis
|
//Calculate Angle for x and y axis
|
||||||
let angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
const angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||||
let cardinalityPosition = { x: 0, y: 0 };
|
const cardinalityPosition = { x: 0, y: 0 };
|
||||||
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
||||||
cardinalityPosition.x = Math.sin(angle) * d + (points[0].x + center.x) / 2;
|
cardinalityPosition.x = Math.sin(angle) * d + (points[0].x + center.x) / 2;
|
||||||
cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2;
|
cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2;
|
||||||
|
@ -426,11 +428,11 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => {
|
||||||
prevPoint = point;
|
prevPoint = point;
|
||||||
});
|
});
|
||||||
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
||||||
let d = 10 + terminalMarkerSize * 0.5;
|
const d = 10 + terminalMarkerSize * 0.5;
|
||||||
//Calculate Angle for x and y axis
|
//Calculate Angle for x and y axis
|
||||||
let angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
const angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||||
|
|
||||||
let cardinalityPosition = { x: 0, y: 0 };
|
const cardinalityPosition = { x: 0, y: 0 };
|
||||||
|
|
||||||
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
||||||
|
|
||||||
|
@ -486,10 +488,10 @@ export const generateId = () => {
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
function makeid(length) {
|
function makeid(length) {
|
||||||
var result = '';
|
let result = '';
|
||||||
var characters = '0123456789abcdef';
|
const characters = '0123456789abcdef';
|
||||||
var charactersLength = characters.length;
|
const charactersLength = characters.length;
|
||||||
for (var i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -632,7 +634,8 @@ const breakString = memoize(
|
||||||
* If the wrapped text text has greater height, we extend the height, so it's value won't overflow.
|
* If the wrapped text text has greater height, we extend the height, so it's value won't overflow.
|
||||||
*
|
*
|
||||||
* @param {any} text The text to measure
|
* @param {any} text The text to measure
|
||||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||||
|
* resulting size
|
||||||
* @returns {any} - The height for the given text
|
* @returns {any} - The height for the given text
|
||||||
*/
|
*/
|
||||||
export const calculateTextHeight = function (text, config) {
|
export const calculateTextHeight = function (text, config) {
|
||||||
|
@ -647,7 +650,8 @@ export const calculateTextHeight = function (text, config) {
|
||||||
* This calculates the width of the given text, font size and family.
|
* This calculates the width of the given text, font size and family.
|
||||||
*
|
*
|
||||||
* @param {any} text - The text to calculate the width of
|
* @param {any} text - The text to calculate the width of
|
||||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||||
|
* resulting size
|
||||||
* @returns {any} - The width for the given text
|
* @returns {any} - The width for the given text
|
||||||
*/
|
*/
|
||||||
export const calculateTextWidth = function (text, config) {
|
export const calculateTextWidth = function (text, config) {
|
||||||
|
@ -656,7 +660,8 @@ export const calculateTextWidth = function (text, config) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This calculates the dimensions of the given text, font size, font family, font weight, and margins.
|
* This calculates the dimensions of the given text, font size, font family, font weight, and
|
||||||
|
* margins.
|
||||||
*
|
*
|
||||||
* @param {any} text - The text to calculate the width of
|
* @param {any} text - The text to calculate the width of
|
||||||
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
|
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
|
||||||
|
@ -676,7 +681,7 @@ export const calculateTextDimensions = memoize(
|
||||||
// of sans-serif.
|
// of sans-serif.
|
||||||
const fontFamilies = ['sans-serif', fontFamily];
|
const fontFamilies = ['sans-serif', fontFamily];
|
||||||
const lines = text.split(common.lineBreakRegex);
|
const lines = text.split(common.lineBreakRegex);
|
||||||
let dims = [];
|
const dims = [];
|
||||||
|
|
||||||
const body = select('body');
|
const body = select('body');
|
||||||
// We don't want to leak DOM elements - if a removal operation isn't available
|
// We don't want to leak DOM elements - if a removal operation isn't available
|
||||||
|
@ -687,10 +692,10 @@ export const calculateTextDimensions = memoize(
|
||||||
|
|
||||||
const g = body.append('svg');
|
const g = body.append('svg');
|
||||||
|
|
||||||
for (let fontFamily of fontFamilies) {
|
for (const fontFamily of fontFamilies) {
|
||||||
let cheight = 0;
|
let cheight = 0;
|
||||||
let dim = { width: 0, height: 0, lineHeight: 0 };
|
const dim = { width: 0, height: 0, lineHeight: 0 };
|
||||||
for (let line of lines) {
|
for (const line of lines) {
|
||||||
const textObj = getTextObj();
|
const textObj = getTextObj();
|
||||||
textObj.text = line;
|
textObj.text = line;
|
||||||
const textElem = drawSimpleText(g, textObj)
|
const textElem = drawSimpleText(g, textObj)
|
||||||
|
@ -698,7 +703,7 @@ export const calculateTextDimensions = memoize(
|
||||||
.style('font-weight', fontWeight)
|
.style('font-weight', fontWeight)
|
||||||
.style('font-family', fontFamily);
|
.style('font-family', fontFamily);
|
||||||
|
|
||||||
let bBox = (textElem._groups || textElem)[0][0].getBBox();
|
const bBox = (textElem._groups || textElem)[0][0].getBBox();
|
||||||
dim.width = Math.round(Math.max(dim.width, bBox.width));
|
dim.width = Math.round(Math.max(dim.width, bBox.width));
|
||||||
cheight = Math.round(bBox.height);
|
cheight = Math.round(bBox.height);
|
||||||
dim.height += cheight;
|
dim.height += cheight;
|
||||||
|
@ -709,7 +714,7 @@ export const calculateTextDimensions = memoize(
|
||||||
|
|
||||||
g.remove();
|
g.remove();
|
||||||
|
|
||||||
let index =
|
const index =
|
||||||
isNaN(dims[1].height) ||
|
isNaN(dims[1].height) ||
|
||||||
isNaN(dims[1].width) ||
|
isNaN(dims[1].width) ||
|
||||||
isNaN(dims[1].lineHeight) ||
|
isNaN(dims[1].lineHeight) ||
|
||||||
|
@ -727,10 +732,11 @@ export const calculateTextDimensions = memoize(
|
||||||
* Applys d3 attributes
|
* Applys d3 attributes
|
||||||
*
|
*
|
||||||
* @param {any} d3Elem D3 Element to apply the attributes onto
|
* @param {any} d3Elem D3 Element to apply the attributes onto
|
||||||
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
|
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of
|
||||||
|
* attributes
|
||||||
*/
|
*/
|
||||||
const d3Attrs = function (d3Elem, attrs) {
|
const d3Attrs = function (d3Elem, attrs) {
|
||||||
for (let attr of attrs) {
|
for (const attr of attrs) {
|
||||||
d3Elem.attr(attr[0], attr[1]);
|
d3Elem.attr(attr[0], attr[1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -860,18 +866,12 @@ export interface DetailedError {
|
||||||
hash: any;
|
hash: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @param error */
|
||||||
*
|
|
||||||
* @param error
|
|
||||||
*/
|
|
||||||
export function isDetailedError(error: unknown): error is DetailedError {
|
export function isDetailedError(error: unknown): error is DetailedError {
|
||||||
return 'str' in error;
|
return 'str' in error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @param error */
|
||||||
*
|
|
||||||
* @param error
|
|
||||||
*/
|
|
||||||
export function getErrorMessage(error: unknown): string {
|
export function getErrorMessage(error: unknown): string {
|
||||||
if (error instanceof Error) return error.message;
|
if (error instanceof Error) return error.message;
|
||||||
return String(error);
|
return String(error);
|
||||||
|
|
Loading…
Reference in New Issue