mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-12 03:49:43 +02:00
Merge branch 'develop' into knsv/mindmap-refactoring
This commit is contained in:
5
.changeset/large-mirrors-cheer.md
Normal file
5
.changeset/large-mirrors-cheer.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Update casing of ID in requirement diagram
|
5
.changeset/smart-humans-cover.md
Normal file
5
.changeset/smart-humans-cover.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Update flowchart direction TD's behavior to be the same as TB
|
189
docs/diagrams/flowchart-code-flow.mmd
Normal file
189
docs/diagrams/flowchart-code-flow.mmd
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDiagram.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDb.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDetector.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/styles.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/types.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowChartShapes.js"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/elk/detector.ts"
|
||||||
|
generationTime: 2025-07-23T10:31:53.266Z
|
||||||
|
---
|
||||||
|
flowchart TD
|
||||||
|
%% Entry Points and Detection
|
||||||
|
Input["User Input Text"] --> Detection{Detection Phase}
|
||||||
|
|
||||||
|
Detection --> flowDetector["flowDetector.ts<br/>detector(txt, config)"]
|
||||||
|
Detection --> flowDetectorV2["flowDetector-v2.ts<br/>detector(txt, config)"]
|
||||||
|
Detection --> elkDetector["elk/detector.ts<br/>detector(txt, config)"]
|
||||||
|
|
||||||
|
flowDetector --> |"Checks /^\s*graph/"| DetectLegacy{Legacy Flowchart?}
|
||||||
|
flowDetectorV2 --> |"Checks /^\s*flowchart/"| DetectNew{New Flowchart?}
|
||||||
|
elkDetector --> |"Checks /^\s*flowchart-elk/"| DetectElk{ELK Layout?}
|
||||||
|
|
||||||
|
DetectLegacy --> |Yes| LoadDiagram
|
||||||
|
DetectNew --> |Yes| LoadDiagram
|
||||||
|
DetectElk --> |Yes| LoadDiagram
|
||||||
|
|
||||||
|
%% Loading Phase
|
||||||
|
LoadDiagram["loader() function"] --> flowDiagram["flowDiagram.ts<br/>diagram object"]
|
||||||
|
|
||||||
|
flowDiagram --> DiagramStructure{Diagram Components}
|
||||||
|
DiagramStructure --> Parser["parser: flowParser"]
|
||||||
|
DiagramStructure --> Database["db: new FlowDB()"]
|
||||||
|
DiagramStructure --> Renderer["renderer: flowRenderer-v3-unified"]
|
||||||
|
DiagramStructure --> Styles["styles: flowStyles"]
|
||||||
|
DiagramStructure --> Init["init: (cnf: MermaidConfig)"]
|
||||||
|
|
||||||
|
%% Parser Phase
|
||||||
|
Parser --> flowParser["parser/flowParser.ts<br/>newParser.parse(src)"]
|
||||||
|
flowParser --> |"Preprocesses src"| RemoveWhitespace["Remove trailing whitespace<br/>src.replace(/}\s*\n/g, '}\n')"]
|
||||||
|
RemoveWhitespace --> flowJison["parser/flow.jison<br/>flowJisonParser.parse(newSrc)"]
|
||||||
|
|
||||||
|
flowJison --> ParseGraph["Parse Graph Structure"]
|
||||||
|
ParseGraph --> ParseVertices["Parse Vertices"]
|
||||||
|
ParseGraph --> ParseEdges["Parse Edges"]
|
||||||
|
ParseGraph --> ParseSubgraphs["Parse Subgraphs"]
|
||||||
|
ParseGraph --> ParseClasses["Parse Classes"]
|
||||||
|
ParseGraph --> ParseStyles["Parse Styles"]
|
||||||
|
|
||||||
|
%% Database Phase - FlowDB Class
|
||||||
|
Database --> FlowDBClass["flowDb.ts<br/>FlowDB class"]
|
||||||
|
|
||||||
|
FlowDBClass --> DBInit["constructor()<br/>- Initialize counters<br/>- Bind methods<br/>- Setup toolTips<br/>- Call clear()"]
|
||||||
|
|
||||||
|
DBInit --> DBMethods{FlowDB Methods}
|
||||||
|
|
||||||
|
DBMethods --> addVertex["addVertex(id, textObj, type, style,<br/>classes, dir, props, metadata)"]
|
||||||
|
DBMethods --> addLink["addLink(_start[], _end[], linkData)"]
|
||||||
|
DBMethods --> addSingleLink["addSingleLink(_start, _end, type, id)"]
|
||||||
|
DBMethods --> setDirection["setDirection(dir)"]
|
||||||
|
DBMethods --> addSubGraph["addSubGraph(nodes[], id, title)"]
|
||||||
|
DBMethods --> addClass["addClass(id, style)"]
|
||||||
|
DBMethods --> setClass["setClass(ids, className)"]
|
||||||
|
DBMethods --> setTooltip["setTooltip(ids, tooltip)"]
|
||||||
|
DBMethods --> setClickEvent["setClickEvent(id, functionName, args)"]
|
||||||
|
DBMethods --> setClickFun["setClickFun(id, functionName, args)"]
|
||||||
|
|
||||||
|
%% Vertex Processing
|
||||||
|
addVertex --> VertexProcess{Vertex Processing}
|
||||||
|
VertexProcess --> CreateVertex["Create FlowVertex object<br/>- id, labelType, domId<br/>- styles[], classes[]"]
|
||||||
|
VertexProcess --> SanitizeText["sanitizeText(textObj.text)"]
|
||||||
|
VertexProcess --> ParseMetadata["Parse YAML metadata<br/>yaml.load(yamlData)"]
|
||||||
|
VertexProcess --> SetVertexProps["Set vertex properties<br/>- shape, label, icon, form<br/>- pos, img, constraint, w, h"]
|
||||||
|
|
||||||
|
%% Edge Processing
|
||||||
|
addSingleLink --> EdgeProcess{Edge Processing}
|
||||||
|
EdgeProcess --> CreateEdge["Create FlowEdge object<br/>- start, end, type, text<br/>- labelType, classes[]"]
|
||||||
|
EdgeProcess --> ProcessLinkText["Process link text<br/>- sanitizeText()<br/>- strip quotes"]
|
||||||
|
EdgeProcess --> SetEdgeProps["Set edge properties<br/>- type, stroke, length"]
|
||||||
|
EdgeProcess --> GenerateEdgeId["Generate edge ID<br/>getEdgeId(start, end, counter)"]
|
||||||
|
EdgeProcess --> ValidateEdgeLimit["Validate edge limit<br/>maxEdges check"]
|
||||||
|
|
||||||
|
%% Data Collection
|
||||||
|
DBMethods --> GetData["getData()"]
|
||||||
|
GetData --> CollectNodes["Collect nodes[] from vertices"]
|
||||||
|
GetData --> CollectEdges["Collect edges[] from edges"]
|
||||||
|
GetData --> ProcessSubGraphs["Process subgraphs<br/>- parentDB Map<br/>- subGraphDB Map"]
|
||||||
|
GetData --> AddNodeFromVertex["addNodeFromVertex()<br/>for each vertex"]
|
||||||
|
GetData --> ProcessEdgeTypes["destructEdgeType()<br/>arrowTypeStart, arrowTypeEnd"]
|
||||||
|
|
||||||
|
%% Node Creation
|
||||||
|
AddNodeFromVertex --> NodeCreation{Node Creation}
|
||||||
|
NodeCreation --> FindExistingNode["findNode(nodes, vertex.id)"]
|
||||||
|
NodeCreation --> CreateBaseNode["Create base node<br/>- id, label, parentId<br/>- cssStyles, cssClasses<br/>- shape, domId, tooltip"]
|
||||||
|
NodeCreation --> GetCompiledStyles["getCompiledStyles(classDefs)"]
|
||||||
|
NodeCreation --> GetTypeFromVertex["getTypeFromVertex(vertex)"]
|
||||||
|
|
||||||
|
%% Rendering Phase
|
||||||
|
Renderer --> flowRendererV3["flowRenderer-v3-unified.ts<br/>draw(text, id, version, diag)"]
|
||||||
|
|
||||||
|
flowRendererV3 --> RenderInit["Initialize rendering<br/>- getConfig()<br/>- handle securityLevel<br/>- getDiagramElement()"]
|
||||||
|
|
||||||
|
RenderInit --> GetLayoutData["diag.db.getData()<br/>as LayoutData"]
|
||||||
|
GetLayoutData --> SetupLayoutData["Setup layout data<br/>- type, layoutAlgorithm<br/>- direction, spacing<br/>- markers, diagramId"]
|
||||||
|
|
||||||
|
SetupLayoutData --> CallRender["render(data4Layout, svg)"]
|
||||||
|
CallRender --> SetupViewPort["setupViewPortForSVG(svg, padding)"]
|
||||||
|
SetupViewPort --> ProcessLinks["Process vertex links<br/>- create anchor elements<br/>- handle click events"]
|
||||||
|
|
||||||
|
%% Shape Rendering
|
||||||
|
CallRender --> ShapeSystem["flowChartShapes.js<br/>Shape Functions"]
|
||||||
|
|
||||||
|
ShapeSystem --> ShapeFunctions{Shape Functions}
|
||||||
|
ShapeFunctions --> question["question(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> hexagon["hexagon(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> rect_left_inv_arrow["rect_left_inv_arrow(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> lean_right["lean_right(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> lean_left["lean_left(parent, bbox, node)"]
|
||||||
|
|
||||||
|
ShapeFunctions --> insertPolygonShape["insertPolygonShape(parent, w, h, points)"]
|
||||||
|
ShapeFunctions --> intersectPolygon["intersectPolygon(node, points, point)"]
|
||||||
|
ShapeFunctions --> intersectRect["intersectRect(node, point)"]
|
||||||
|
|
||||||
|
%% Styling System
|
||||||
|
Styles --> stylesTS["styles.ts<br/>getStyles(options)"]
|
||||||
|
stylesTS --> StyleOptions["FlowChartStyleOptions<br/>- arrowheadColor, border2<br/>- clusterBkg, mainBkg<br/>- fontFamily, textColor"]
|
||||||
|
|
||||||
|
StyleOptions --> GenerateCSS["Generate CSS styles<br/>- .label, .cluster-label<br/>- .node, .edgePath<br/>- .flowchart-link, .edgeLabel"]
|
||||||
|
GenerateCSS --> GetIconStyles["getIconStyles()"]
|
||||||
|
|
||||||
|
%% Type System
|
||||||
|
Parser --> TypeSystem["types.ts<br/>Type Definitions"]
|
||||||
|
TypeSystem --> FlowVertex["FlowVertex interface"]
|
||||||
|
TypeSystem --> FlowEdge["FlowEdge interface"]
|
||||||
|
TypeSystem --> FlowClass["FlowClass interface"]
|
||||||
|
TypeSystem --> FlowSubGraph["FlowSubGraph interface"]
|
||||||
|
TypeSystem --> FlowVertexTypeParam["FlowVertexTypeParam<br/>Shape types"]
|
||||||
|
|
||||||
|
%% Utility Functions
|
||||||
|
DBMethods --> UtilityFunctions{Utility Functions}
|
||||||
|
UtilityFunctions --> lookUpDomId["lookUpDomId(id)"]
|
||||||
|
UtilityFunctions --> getClasses["getClasses()"]
|
||||||
|
UtilityFunctions --> getDirection["getDirection()"]
|
||||||
|
UtilityFunctions --> getVertices["getVertices()"]
|
||||||
|
UtilityFunctions --> getEdges["getEdges()"]
|
||||||
|
UtilityFunctions --> getSubGraphs["getSubGraphs()"]
|
||||||
|
UtilityFunctions --> clear["clear()"]
|
||||||
|
UtilityFunctions --> defaultConfig["defaultConfig()"]
|
||||||
|
|
||||||
|
%% Event Handling
|
||||||
|
ProcessLinks --> EventHandling{Event Handling}
|
||||||
|
EventHandling --> setupToolTips["setupToolTips(element)"]
|
||||||
|
EventHandling --> bindFunctions["bindFunctions(element)"]
|
||||||
|
EventHandling --> runFunc["utils.runFunc(functionName, args)"]
|
||||||
|
|
||||||
|
%% Common Database Functions
|
||||||
|
DBMethods --> CommonDB["commonDb.js functions"]
|
||||||
|
CommonDB --> setAccTitle["setAccTitle()"]
|
||||||
|
CommonDB --> getAccTitle["getAccTitle()"]
|
||||||
|
CommonDB --> setAccDescription["setAccDescription()"]
|
||||||
|
CommonDB --> getAccDescription["getAccDescription()"]
|
||||||
|
CommonDB --> setDiagramTitle["setDiagramTitle()"]
|
||||||
|
CommonDB --> getDiagramTitle["getDiagramTitle()"]
|
||||||
|
CommonDB --> commonClear["clear()"]
|
||||||
|
|
||||||
|
%% Final Output
|
||||||
|
ProcessLinks --> FinalSVG["Final SVG Output"]
|
||||||
|
|
||||||
|
%% Layout Algorithm Selection
|
||||||
|
SetupLayoutData --> LayoutAlgorithm{Layout Algorithm}
|
||||||
|
LayoutAlgorithm --> Dagre["dagre<br/>(default)"]
|
||||||
|
LayoutAlgorithm --> DagreWrapper["dagre-wrapper<br/>(v2 renderer)"]
|
||||||
|
LayoutAlgorithm --> ELK["elk<br/>(external package)"]
|
||||||
|
|
||||||
|
%% Testing Components
|
||||||
|
FlowDBClass --> TestFiles["Test Files"]
|
||||||
|
TestFiles --> flowDbSpec["flowDb.spec.ts"]
|
||||||
|
TestFiles --> flowChartShapesSpec["flowChartShapes.spec.js"]
|
||||||
|
TestFiles --> ParserTests["parser/*.spec.js files<br/>- flow-text.spec.js<br/>- flow-edges.spec.js<br/>- flow-style.spec.js<br/>- subgraph.spec.js"]
|
||||||
|
|
||||||
|
%% Configuration
|
||||||
|
Init --> ConfigSetup["Configuration Setup"]
|
||||||
|
ConfigSetup --> FlowchartConfig["cnf.flowchart config"]
|
||||||
|
ConfigSetup --> ArrowMarkers["arrowMarkerAbsolute"]
|
||||||
|
ConfigSetup --> LayoutConfig["layout config"]
|
||||||
|
ConfigSetup --> SetConfig["setConfig() calls"]
|
307
docs/diagrams/mermaid-api-sequence.mmd
Normal file
307
docs/diagrams/mermaid-api-sequence.mmd
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/mermaidAPI.ts"
|
||||||
|
- "File: /packages/mermaid/src/mermaid.ts"
|
||||||
|
generationTime: 2025-01-28T16:30:00.000Z
|
||||||
|
---
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as User/Browser
|
||||||
|
participant Mermaid as mermaid.ts
|
||||||
|
participant Queue as executionQueue
|
||||||
|
participant API as mermaidAPI.ts
|
||||||
|
participant Config as configApi
|
||||||
|
participant Preprocessor as preprocessDiagram
|
||||||
|
participant DiagramAPI as diagram-api
|
||||||
|
participant Diagram as Diagram.fromText
|
||||||
|
participant Renderer as diagram.renderer
|
||||||
|
participant Styles as Styling System
|
||||||
|
participant DOM as DOM/SVG
|
||||||
|
|
||||||
|
Note over User, DOM: Mermaid Complete API Flow
|
||||||
|
|
||||||
|
%% Initialization Phase
|
||||||
|
User->>+Mermaid: mermaid.initialize(config)
|
||||||
|
Mermaid->>+API: mermaidAPI.initialize(config)
|
||||||
|
|
||||||
|
API->>API: assignWithDepth({}, userOptions)
|
||||||
|
API->>API: handle legacy fontFamily config
|
||||||
|
API->>Config: saveConfigFromInitialize(options)
|
||||||
|
|
||||||
|
alt Theme Configuration Available
|
||||||
|
API->>API: check if theme in theme object
|
||||||
|
API->>API: set themeVariables from theme
|
||||||
|
else Default Theme
|
||||||
|
API->>API: use default theme variables
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>Config: setSiteConfig(options) or getSiteConfig()
|
||||||
|
API->>API: setLogLevel(config.logLevel)
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
|
||||||
|
API-->>-Mermaid: initialization complete
|
||||||
|
Mermaid-->>-User: ready to render
|
||||||
|
|
||||||
|
%% Content Loaded Event
|
||||||
|
User->>DOM: document.load event
|
||||||
|
DOM->>+Mermaid: contentLoaded()
|
||||||
|
|
||||||
|
opt startOnLoad is true
|
||||||
|
Mermaid->>Config: getConfig()
|
||||||
|
Config-->>Mermaid: { startOnLoad: true }
|
||||||
|
Mermaid->>Mermaid: run()
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-DOM: event handling complete
|
||||||
|
|
||||||
|
%% Main Run Function
|
||||||
|
User->>+Mermaid: mermaid.run(options)
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: runThrowsErrors(options)
|
||||||
|
Mermaid->>Config: getConfig()
|
||||||
|
Config-->>Mermaid: configuration object
|
||||||
|
|
||||||
|
alt nodes provided
|
||||||
|
Mermaid->>Mermaid: use provided nodes
|
||||||
|
else querySelector provided
|
||||||
|
Mermaid->>DOM: document.querySelectorAll(querySelector)
|
||||||
|
DOM-->>Mermaid: nodesToProcess
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: new InitIDGenerator(deterministicIds, seed)
|
||||||
|
|
||||||
|
loop For each diagram element
|
||||||
|
Mermaid->>DOM: check element.getAttribute('data-processed')
|
||||||
|
|
||||||
|
opt not processed
|
||||||
|
Mermaid->>DOM: element.setAttribute('data-processed', 'true')
|
||||||
|
Mermaid->>Mermaid: generate unique id
|
||||||
|
Mermaid->>DOM: get element.innerHTML
|
||||||
|
Mermaid->>Mermaid: entityDecode and clean text
|
||||||
|
Mermaid->>Mermaid: detectInit(txt)
|
||||||
|
|
||||||
|
Mermaid->>Queue: render(id, txt, element)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: processing initiated
|
||||||
|
|
||||||
|
%% Render Function (Queued)
|
||||||
|
activate Queue
|
||||||
|
Queue->>+API: mermaidAPI.render(id, text, container)
|
||||||
|
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
API->>+Preprocessor: processAndSetConfigs(text)
|
||||||
|
|
||||||
|
Preprocessor->>Preprocessor: preprocessDiagram(text)
|
||||||
|
Preprocessor->>Config: reset()
|
||||||
|
Preprocessor->>Config: addDirective(processed.config)
|
||||||
|
Preprocessor-->>-API: { code, config }
|
||||||
|
|
||||||
|
API->>Config: getConfig()
|
||||||
|
Config-->>API: current configuration
|
||||||
|
|
||||||
|
opt text length > maxTextSize
|
||||||
|
API->>API: text = MAX_TEXTLENGTH_EXCEEDED_MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: setup id selectors and element IDs
|
||||||
|
API->>API: determine security level (sandbox/loose)
|
||||||
|
|
||||||
|
%% DOM Setup
|
||||||
|
alt svgContainingElement provided
|
||||||
|
alt isSandboxed
|
||||||
|
API->>DOM: sandboxedIframe(select(svgContainingElement), iFrameID)
|
||||||
|
API->>DOM: select iframe contentDocument body
|
||||||
|
else
|
||||||
|
API->>DOM: select(svgContainingElement)
|
||||||
|
end
|
||||||
|
else no container
|
||||||
|
API->>API: removeExistingElements(document, id, divId, iFrameId)
|
||||||
|
alt isSandboxed
|
||||||
|
API->>DOM: sandboxedIframe(select('body'), iFrameID)
|
||||||
|
else
|
||||||
|
API->>DOM: select('body')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>DOM: appendDivSvgG(root, id, enclosingDivID, fontFamily, XMLNS_XLINK_STD)
|
||||||
|
|
||||||
|
%% Diagram Creation
|
||||||
|
API->>+Diagram: Diagram.fromText(text, { title: processed.title })
|
||||||
|
|
||||||
|
Diagram->>DiagramAPI: detect diagram type
|
||||||
|
Diagram->>DiagramAPI: load appropriate diagram
|
||||||
|
Diagram-->>-API: diagram instance
|
||||||
|
|
||||||
|
opt parsing error occurred
|
||||||
|
API->>+Diagram: Diagram.fromText('error')
|
||||||
|
Diagram-->>-API: error diagram
|
||||||
|
API->>API: store parseEncounteredException
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Style Generation
|
||||||
|
API->>DOM: get svg element and firstChild
|
||||||
|
API->>Renderer: diag.renderer.getClasses(text, diag)
|
||||||
|
Renderer-->>API: diagramClassDefs
|
||||||
|
|
||||||
|
API->>+Styles: createUserStyles(config, diagramType, diagramClassDefs, idSelector)
|
||||||
|
|
||||||
|
Styles->>Styles: createCssStyles(config, classDefs)
|
||||||
|
|
||||||
|
opt config.themeCSS defined
|
||||||
|
Styles->>Styles: append themeCSS
|
||||||
|
end
|
||||||
|
|
||||||
|
opt fontFamily configured
|
||||||
|
Styles->>Styles: add CSS variables for fonts
|
||||||
|
end
|
||||||
|
|
||||||
|
opt classDefs exist
|
||||||
|
loop For each styleClassDef
|
||||||
|
opt has styles
|
||||||
|
Styles->>Styles: cssImportantStyles for each CSS element
|
||||||
|
end
|
||||||
|
opt has textStyles
|
||||||
|
Styles->>Styles: cssImportantStyles for tspan elements
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Styles->>Styles: getStyles(graphType, userCSSstyles, themeVariables)
|
||||||
|
Styles->>Styles: serialize(compile(svgId{allStyles}), stringify)
|
||||||
|
Styles-->>-API: compiled CSS rules
|
||||||
|
|
||||||
|
API->>DOM: create style element
|
||||||
|
API->>DOM: style.innerHTML = rules
|
||||||
|
API->>DOM: svg.insertBefore(style, firstChild)
|
||||||
|
|
||||||
|
%% Diagram Rendering
|
||||||
|
API->>+Renderer: diag.renderer.draw(text, id, version, diag)
|
||||||
|
|
||||||
|
Renderer->>Renderer: diagram-specific rendering logic
|
||||||
|
Renderer->>DOM: create SVG elements
|
||||||
|
Renderer->>DOM: apply positioning and styling
|
||||||
|
Renderer-->>-API: rendered diagram
|
||||||
|
|
||||||
|
opt rendering error
|
||||||
|
alt suppressErrorRendering
|
||||||
|
API->>API: removeTempElements()
|
||||||
|
API->>Mermaid: throw error
|
||||||
|
else
|
||||||
|
API->>Renderer: errorRenderer.draw(text, id, version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Accessibility and Cleanup
|
||||||
|
API->>DOM: select svg element
|
||||||
|
API->>Diagram: diag.db.getAccTitle()
|
||||||
|
API->>Diagram: diag.db.getAccDescription()
|
||||||
|
API->>API: addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr)
|
||||||
|
|
||||||
|
API->>DOM: set xmlns for foreignobject elements
|
||||||
|
API->>DOM: get innerHTML from enclosing div
|
||||||
|
|
||||||
|
API->>+API: cleanUpSvgCode(svgCode, isSandboxed, arrowMarkerAbsolute)
|
||||||
|
|
||||||
|
opt not useArrowMarkerUrls and not sandboxed
|
||||||
|
API->>API: replace marker-end URLs with anchors
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: decodeEntities(svgCode)
|
||||||
|
API->>API: replace <br> with <br/>
|
||||||
|
API-->>-API: cleaned SVG code
|
||||||
|
|
||||||
|
alt isSandboxed
|
||||||
|
API->>+API: putIntoIFrame(svgCode, svgEl)
|
||||||
|
API->>API: calculate iframe height
|
||||||
|
API->>API: toBase64 encode SVG content
|
||||||
|
API->>API: create iframe with sandbox attributes
|
||||||
|
API-->>-API: iframe HTML
|
||||||
|
else not loose security
|
||||||
|
API->>API: DOMPurify.sanitize(svgCode, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: attachFunctions()
|
||||||
|
API->>API: removeTempElements()
|
||||||
|
|
||||||
|
opt parseEncounteredException
|
||||||
|
API->>Mermaid: throw parseEncounteredException
|
||||||
|
end
|
||||||
|
|
||||||
|
API-->>-Queue: { diagramType, svg: svgCode, bindFunctions }
|
||||||
|
|
||||||
|
%% Return to Web Integration
|
||||||
|
activate Mermaid
|
||||||
|
Queue-->>Mermaid: render result
|
||||||
|
Mermaid->>DOM: element.innerHTML = svg
|
||||||
|
|
||||||
|
opt postRenderCallback
|
||||||
|
Mermaid->>User: postRenderCallback(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
opt bindFunctions exist
|
||||||
|
Mermaid->>DOM: bindFunctions(element)
|
||||||
|
end
|
||||||
|
deactivate Mermaid
|
||||||
|
|
||||||
|
%% Parse Function Flow
|
||||||
|
User->>+Mermaid: mermaid.parse(text, parseOptions)
|
||||||
|
activate Queue
|
||||||
|
|
||||||
|
Queue->>+API: mermaidAPI.parse(text, parseOptions)
|
||||||
|
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
API->>Preprocessor: processAndSetConfigs(text)
|
||||||
|
Preprocessor-->>API: { code, config }
|
||||||
|
API->>Diagram: getDiagramFromText(code)
|
||||||
|
Diagram-->>API: diagram instance
|
||||||
|
API-->>-Queue: { diagramType: diagram.type, config }
|
||||||
|
|
||||||
|
Queue-->>-Mermaid: parse result
|
||||||
|
Mermaid-->>-User: ParseResult or false
|
||||||
|
|
||||||
|
%% External Diagram Registration
|
||||||
|
User->>+Mermaid: registerExternalDiagrams(diagrams, options)
|
||||||
|
|
||||||
|
Mermaid->>DiagramAPI: addDiagrams()
|
||||||
|
Mermaid->>DiagramAPI: registerLazyLoadedDiagrams(...diagrams)
|
||||||
|
|
||||||
|
opt lazyLoad is false
|
||||||
|
Mermaid->>DiagramAPI: loadRegisteredDiagrams()
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: registration complete
|
||||||
|
|
||||||
|
%% Error Handling
|
||||||
|
Note over Mermaid, API: Error Handling Throughout
|
||||||
|
alt Error occurs
|
||||||
|
API->>Mermaid: throw error
|
||||||
|
Mermaid->>+Mermaid: handleError(error, errors, parseError)
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: log.warn(error)
|
||||||
|
|
||||||
|
alt isDetailedError
|
||||||
|
Mermaid->>User: parseError(error.str, error.hash)
|
||||||
|
else
|
||||||
|
Mermaid->>User: parseError(error)
|
||||||
|
end
|
||||||
|
|
||||||
|
opt not suppressErrors
|
||||||
|
Mermaid->>User: throw error
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: error handled
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Configuration Details
|
||||||
|
Note over Config: Configuration Functions
|
||||||
|
Note right of Config: Functions:<br/>- reset()<br/>- getConfig()<br/>- setConfig()<br/>- getSiteConfig()<br/>- updateSiteConfig()<br/>- saveConfigFromInitialize()
|
||||||
|
|
||||||
|
Note over Styles: CSS Generation
|
||||||
|
Note right of Styles: Features:<br/>- createCssStyles()<br/>- createUserStyles()<br/>- cssImportantStyles()<br/>- Theme integration<br/>- Class definitions
|
||||||
|
|
||||||
|
Note over API: Security Levels
|
||||||
|
Note right of API: Modes:<br/>- sandbox: iframe isolation<br/>- loose: minimal sanitization<br/>- default: DOMPurify sanitization
|
||||||
|
|
||||||
|
Note over API: Helper Functions
|
||||||
|
Note right of API: Utilities:<br/>- cleanUpSvgCode()<br/>- putIntoIFrame()<br/>- appendDivSvgG()<br/>- removeExistingElements()
|
180
docs/diagrams/mindmap-implementation-sequence.mmd
Normal file
180
docs/diagrams/mindmap-implementation-sequence.mmd
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapDb.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/detector.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/styles.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/svgDraw.ts"
|
||||||
|
generationTime: 2025-01-28T16:00:00.000Z
|
||||||
|
---
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as User Input Text
|
||||||
|
participant Detector as detector.ts
|
||||||
|
participant Loader as DiagramLoader
|
||||||
|
participant Definition as mindmap-definition.ts
|
||||||
|
participant Parser as parser/mindmap.jison
|
||||||
|
participant DB as MindmapDB
|
||||||
|
participant Renderer as mindmapRenderer.ts
|
||||||
|
participant Cytoscape as cytoscape.js
|
||||||
|
participant SVGDraw as svgDraw.ts
|
||||||
|
participant Styles as styles.ts
|
||||||
|
participant Output as Final SVG
|
||||||
|
|
||||||
|
Note over User, Output: Mindmap Implementation Flow
|
||||||
|
|
||||||
|
%% Detection Phase
|
||||||
|
User->>Detector: /^\s*mindmap/ text input
|
||||||
|
activate Detector
|
||||||
|
Detector->>Detector: detector(txt) validates pattern
|
||||||
|
Detector->>Loader: loader() function called
|
||||||
|
deactivate Detector
|
||||||
|
|
||||||
|
activate Loader
|
||||||
|
Loader->>Definition: import mindmap-definition.js
|
||||||
|
deactivate Loader
|
||||||
|
|
||||||
|
%% Core Structure Setup
|
||||||
|
activate Definition
|
||||||
|
Definition->>DB: get db() → new MindmapDB()
|
||||||
|
Definition->>Renderer: setup renderer
|
||||||
|
Definition->>Parser: setup parser
|
||||||
|
Definition->>Styles: setup styles
|
||||||
|
deactivate Definition
|
||||||
|
|
||||||
|
%% Database Initialization
|
||||||
|
activate DB
|
||||||
|
Note over DB: MindmapDB Constructor
|
||||||
|
DB->>DB: initialize nodes array
|
||||||
|
DB->>DB: setup nodeType constants
|
||||||
|
DB->>DB: bind methods
|
||||||
|
DB->>DB: clear() state
|
||||||
|
|
||||||
|
%% Parsing Phase
|
||||||
|
activate Parser
|
||||||
|
User->>Parser: mindmap syntax text
|
||||||
|
|
||||||
|
loop For each node in hierarchy
|
||||||
|
Parser->>DB: addNode(level, id, descr, type)
|
||||||
|
activate DB
|
||||||
|
DB->>DB: sanitizeText(id, descr)
|
||||||
|
DB->>DB: getType(startStr, endStr)
|
||||||
|
Note right of DB: Shape Detection:<br/>[ → RECT<br/>( → ROUNDED_RECT<br/>(( → CIRCLE<br/>)) → BANG<br/>{{ → HEXAGON
|
||||||
|
DB->>DB: getParent(level)
|
||||||
|
DB->>DB: create MindmapNode
|
||||||
|
DB->>DB: add to hierarchy
|
||||||
|
deactivate DB
|
||||||
|
end
|
||||||
|
|
||||||
|
opt Icon/Class Decoration
|
||||||
|
Parser->>DB: decorateNode(decoration)
|
||||||
|
DB->>DB: set icon/class properties
|
||||||
|
end
|
||||||
|
deactivate Parser
|
||||||
|
|
||||||
|
%% Data Preparation
|
||||||
|
Renderer->>DB: getData() for layout
|
||||||
|
activate DB
|
||||||
|
DB->>DB: collect all nodes
|
||||||
|
DB->>DB: build parent-child relationships
|
||||||
|
DB-->>Renderer: return node hierarchy
|
||||||
|
deactivate DB
|
||||||
|
|
||||||
|
%% Rendering Pipeline
|
||||||
|
activate Renderer
|
||||||
|
Note over Renderer: Rendering Phase
|
||||||
|
|
||||||
|
Renderer->>Cytoscape: initialize cytoscape
|
||||||
|
activate Cytoscape
|
||||||
|
|
||||||
|
loop For each node in mindmap
|
||||||
|
Renderer->>Cytoscape: addNodes(mindmap, cy, conf, level)
|
||||||
|
Cytoscape->>Cytoscape: create node data
|
||||||
|
Cytoscape->>Cytoscape: set position (x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
loop For parent-child relationships
|
||||||
|
Renderer->>Cytoscape: add edges
|
||||||
|
Cytoscape->>Cytoscape: create edge data
|
||||||
|
end
|
||||||
|
|
||||||
|
Renderer->>Cytoscape: configure cose-bilkent layout
|
||||||
|
Cytoscape->>Cytoscape: calculate optimal positions
|
||||||
|
Cytoscape-->>Renderer: return positioned graph
|
||||||
|
deactivate Cytoscape
|
||||||
|
|
||||||
|
%% SVG Generation
|
||||||
|
Renderer->>SVGDraw: drawNodes(db, svg, mindmap, section, conf)
|
||||||
|
activate SVGDraw
|
||||||
|
|
||||||
|
loop For each node recursively
|
||||||
|
SVGDraw->>SVGDraw: select shape function
|
||||||
|
|
||||||
|
alt Default Shape
|
||||||
|
SVGDraw->>SVGDraw: defaultBkg() - rounded rectangle
|
||||||
|
else Rectangle Shape
|
||||||
|
SVGDraw->>SVGDraw: rectBkg() - sharp corners
|
||||||
|
else Circle Shape
|
||||||
|
SVGDraw->>SVGDraw: circleBkg() - perfect circle
|
||||||
|
else Cloud Shape
|
||||||
|
SVGDraw->>SVGDraw: cloudBkg() - organic curves
|
||||||
|
else Bang Shape
|
||||||
|
SVGDraw->>SVGDraw: bangBkg() - explosion style
|
||||||
|
else Hexagon Shape
|
||||||
|
SVGDraw->>SVGDraw: hexagonBkg() - six sides
|
||||||
|
end
|
||||||
|
|
||||||
|
SVGDraw->>SVGDraw: create SVG elements
|
||||||
|
SVGDraw->>SVGDraw: add text labels
|
||||||
|
SVGDraw->>SVGDraw: position node
|
||||||
|
|
||||||
|
opt Node has children
|
||||||
|
SVGDraw->>SVGDraw: drawNodes() recursive call
|
||||||
|
end
|
||||||
|
end
|
||||||
|
deactivate SVGDraw
|
||||||
|
|
||||||
|
%% Edge Rendering
|
||||||
|
Renderer->>Renderer: drawEdges(edgesEl, cy)
|
||||||
|
loop For each edge
|
||||||
|
Renderer->>Renderer: extract edge bounds
|
||||||
|
Renderer->>Renderer: draw SVG path
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Styling Application
|
||||||
|
Renderer->>Styles: getStyles(options)
|
||||||
|
activate Styles
|
||||||
|
|
||||||
|
Styles->>Styles: genSections(options)
|
||||||
|
loop For THEME_COLOR_LIMIT sections
|
||||||
|
Styles->>Styles: generate color scale
|
||||||
|
Styles->>Styles: create CSS rules
|
||||||
|
Note right of Styles: .section-X fills<br/>.edge-depth-X widths<br/>.node-icon-X colors
|
||||||
|
end
|
||||||
|
|
||||||
|
Styles->>Styles: apply theme integration
|
||||||
|
Styles-->>Renderer: return compiled CSS
|
||||||
|
deactivate Styles
|
||||||
|
|
||||||
|
%% Final Assembly
|
||||||
|
Renderer->>Output: selectSvgElement()
|
||||||
|
Renderer->>Output: setupGraphViewbox()
|
||||||
|
Renderer->>Output: apply styles
|
||||||
|
Renderer->>Output: add interactive elements
|
||||||
|
deactivate Renderer
|
||||||
|
|
||||||
|
activate Output
|
||||||
|
Note over Output: Final Mindmap Features
|
||||||
|
Output->>Output: responsive layout
|
||||||
|
Output->>Output: accessibility attributes
|
||||||
|
Output->>Output: hover effects
|
||||||
|
Output->>Output: click handling
|
||||||
|
Output-->>User: rendered mindmap
|
||||||
|
deactivate Output
|
||||||
|
|
||||||
|
%% Configuration Details
|
||||||
|
Note over DB, Styles: Configuration Options
|
||||||
|
Note right of DB: Padding Calculations:<br/>Base padding from config<br/>RECT: ×2 padding<br/>ROUNDED_RECT: ×2 padding<br/>HEXAGON: ×2 padding
|
||||||
|
Note right of Styles: Section Management:<br/>MAX_SECTIONS = 12<br/>Dynamic color generation<br/>Git theme integration
|
||||||
|
Note right of Renderer: Layout Parameters:<br/>Cytoscape configuration<br/>coseBilkent settings<br/>Node spacing rules
|
@@ -97,8 +97,8 @@
|
|||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-cypress": "^4.3.0",
|
"eslint-plugin-cypress": "^4.3.0",
|
||||||
"eslint-plugin-html": "^8.1.3",
|
"eslint-plugin-html": "^8.1.3",
|
||||||
"eslint-plugin-jest": "^28.11.2",
|
"eslint-plugin-jest": "^28.14.0",
|
||||||
"eslint-plugin-jsdoc": "^50.6.17",
|
"eslint-plugin-jsdoc": "^50.8.0",
|
||||||
"eslint-plugin-json": "^4.0.1",
|
"eslint-plugin-json": "^4.0.1",
|
||||||
"eslint-plugin-lodash": "^8.0.0",
|
"eslint-plugin-lodash": "^8.0.0",
|
||||||
"eslint-plugin-markdown": "^5.1.0",
|
"eslint-plugin-markdown": "^5.1.0",
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"tsx": "^4.7.3",
|
"tsx": "^4.7.3",
|
||||||
"typescript": "~5.7.3",
|
"typescript": "~5.7.3",
|
||||||
"typescript-eslint": "^8.32.1",
|
"typescript-eslint": "^8.38.0",
|
||||||
"vite": "^7.0.3",
|
"vite": "^7.0.3",
|
||||||
"vite-plugin-istanbul": "^7.0.0",
|
"vite-plugin-istanbul": "^7.0.0",
|
||||||
"vitest": "^3.0.6"
|
"vitest": "^3.0.6"
|
||||||
|
@@ -165,3 +165,20 @@ describe('flow db getData', () => {
|
|||||||
expect(edges[3].curve).toBe('stepBefore');
|
expect(edges[3].curve).toBe('stepBefore');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('flow db direction', () => {
|
||||||
|
let flowDb: FlowDB;
|
||||||
|
beforeEach(() => {
|
||||||
|
flowDb = new FlowDB();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set direction to TB when TD is set', () => {
|
||||||
|
flowDb.setDirection('TD');
|
||||||
|
expect(flowDb.getDirection()).toBe('TB');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should correctly set direction irrespective of leading spaces', () => {
|
||||||
|
flowDb.setDirection(' TD');
|
||||||
|
expect(flowDb.getDirection()).toBe('TB');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@@ -406,7 +406,8 @@ You have to call mermaid.initialize.`
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public setDirection(dir: string) {
|
public setDirection(dir: string) {
|
||||||
this.direction = dir;
|
this.direction = dir.trim();
|
||||||
|
|
||||||
if (/.*</.exec(this.direction)) {
|
if (/.*</.exec(this.direction)) {
|
||||||
this.direction = 'RL';
|
this.direction = 'RL';
|
||||||
}
|
}
|
||||||
|
189
packages/mermaid/src/docs/diagrams/flowchart-code-flow.mmd
Normal file
189
packages/mermaid/src/docs/diagrams/flowchart-code-flow.mmd
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDiagram.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDb.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDetector.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/styles.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/types.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/flowChartShapes.js"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/flowchart/elk/detector.ts"
|
||||||
|
generationTime: 2025-07-23T10:31:53.266Z
|
||||||
|
---
|
||||||
|
flowchart TD
|
||||||
|
%% Entry Points and Detection
|
||||||
|
Input["User Input Text"] --> Detection{Detection Phase}
|
||||||
|
|
||||||
|
Detection --> flowDetector["flowDetector.ts<br/>detector(txt, config)"]
|
||||||
|
Detection --> flowDetectorV2["flowDetector-v2.ts<br/>detector(txt, config)"]
|
||||||
|
Detection --> elkDetector["elk/detector.ts<br/>detector(txt, config)"]
|
||||||
|
|
||||||
|
flowDetector --> |"Checks /^\s*graph/"| DetectLegacy{Legacy Flowchart?}
|
||||||
|
flowDetectorV2 --> |"Checks /^\s*flowchart/"| DetectNew{New Flowchart?}
|
||||||
|
elkDetector --> |"Checks /^\s*flowchart-elk/"| DetectElk{ELK Layout?}
|
||||||
|
|
||||||
|
DetectLegacy --> |Yes| LoadDiagram
|
||||||
|
DetectNew --> |Yes| LoadDiagram
|
||||||
|
DetectElk --> |Yes| LoadDiagram
|
||||||
|
|
||||||
|
%% Loading Phase
|
||||||
|
LoadDiagram["loader() function"] --> flowDiagram["flowDiagram.ts<br/>diagram object"]
|
||||||
|
|
||||||
|
flowDiagram --> DiagramStructure{Diagram Components}
|
||||||
|
DiagramStructure --> Parser["parser: flowParser"]
|
||||||
|
DiagramStructure --> Database["db: new FlowDB()"]
|
||||||
|
DiagramStructure --> Renderer["renderer: flowRenderer-v3-unified"]
|
||||||
|
DiagramStructure --> Styles["styles: flowStyles"]
|
||||||
|
DiagramStructure --> Init["init: (cnf: MermaidConfig)"]
|
||||||
|
|
||||||
|
%% Parser Phase
|
||||||
|
Parser --> flowParser["parser/flowParser.ts<br/>newParser.parse(src)"]
|
||||||
|
flowParser --> |"Preprocesses src"| RemoveWhitespace["Remove trailing whitespace<br/>src.replace(/}\s*\n/g, '}\n')"]
|
||||||
|
RemoveWhitespace --> flowJison["parser/flow.jison<br/>flowJisonParser.parse(newSrc)"]
|
||||||
|
|
||||||
|
flowJison --> ParseGraph["Parse Graph Structure"]
|
||||||
|
ParseGraph --> ParseVertices["Parse Vertices"]
|
||||||
|
ParseGraph --> ParseEdges["Parse Edges"]
|
||||||
|
ParseGraph --> ParseSubgraphs["Parse Subgraphs"]
|
||||||
|
ParseGraph --> ParseClasses["Parse Classes"]
|
||||||
|
ParseGraph --> ParseStyles["Parse Styles"]
|
||||||
|
|
||||||
|
%% Database Phase - FlowDB Class
|
||||||
|
Database --> FlowDBClass["flowDb.ts<br/>FlowDB class"]
|
||||||
|
|
||||||
|
FlowDBClass --> DBInit["constructor()<br/>- Initialize counters<br/>- Bind methods<br/>- Setup toolTips<br/>- Call clear()"]
|
||||||
|
|
||||||
|
DBInit --> DBMethods{FlowDB Methods}
|
||||||
|
|
||||||
|
DBMethods --> addVertex["addVertex(id, textObj, type, style,<br/>classes, dir, props, metadata)"]
|
||||||
|
DBMethods --> addLink["addLink(_start[], _end[], linkData)"]
|
||||||
|
DBMethods --> addSingleLink["addSingleLink(_start, _end, type, id)"]
|
||||||
|
DBMethods --> setDirection["setDirection(dir)"]
|
||||||
|
DBMethods --> addSubGraph["addSubGraph(nodes[], id, title)"]
|
||||||
|
DBMethods --> addClass["addClass(id, style)"]
|
||||||
|
DBMethods --> setClass["setClass(ids, className)"]
|
||||||
|
DBMethods --> setTooltip["setTooltip(ids, tooltip)"]
|
||||||
|
DBMethods --> setClickEvent["setClickEvent(id, functionName, args)"]
|
||||||
|
DBMethods --> setClickFun["setClickFun(id, functionName, args)"]
|
||||||
|
|
||||||
|
%% Vertex Processing
|
||||||
|
addVertex --> VertexProcess{Vertex Processing}
|
||||||
|
VertexProcess --> CreateVertex["Create FlowVertex object<br/>- id, labelType, domId<br/>- styles[], classes[]"]
|
||||||
|
VertexProcess --> SanitizeText["sanitizeText(textObj.text)"]
|
||||||
|
VertexProcess --> ParseMetadata["Parse YAML metadata<br/>yaml.load(yamlData)"]
|
||||||
|
VertexProcess --> SetVertexProps["Set vertex properties<br/>- shape, label, icon, form<br/>- pos, img, constraint, w, h"]
|
||||||
|
|
||||||
|
%% Edge Processing
|
||||||
|
addSingleLink --> EdgeProcess{Edge Processing}
|
||||||
|
EdgeProcess --> CreateEdge["Create FlowEdge object<br/>- start, end, type, text<br/>- labelType, classes[]"]
|
||||||
|
EdgeProcess --> ProcessLinkText["Process link text<br/>- sanitizeText()<br/>- strip quotes"]
|
||||||
|
EdgeProcess --> SetEdgeProps["Set edge properties<br/>- type, stroke, length"]
|
||||||
|
EdgeProcess --> GenerateEdgeId["Generate edge ID<br/>getEdgeId(start, end, counter)"]
|
||||||
|
EdgeProcess --> ValidateEdgeLimit["Validate edge limit<br/>maxEdges check"]
|
||||||
|
|
||||||
|
%% Data Collection
|
||||||
|
DBMethods --> GetData["getData()"]
|
||||||
|
GetData --> CollectNodes["Collect nodes[] from vertices"]
|
||||||
|
GetData --> CollectEdges["Collect edges[] from edges"]
|
||||||
|
GetData --> ProcessSubGraphs["Process subgraphs<br/>- parentDB Map<br/>- subGraphDB Map"]
|
||||||
|
GetData --> AddNodeFromVertex["addNodeFromVertex()<br/>for each vertex"]
|
||||||
|
GetData --> ProcessEdgeTypes["destructEdgeType()<br/>arrowTypeStart, arrowTypeEnd"]
|
||||||
|
|
||||||
|
%% Node Creation
|
||||||
|
AddNodeFromVertex --> NodeCreation{Node Creation}
|
||||||
|
NodeCreation --> FindExistingNode["findNode(nodes, vertex.id)"]
|
||||||
|
NodeCreation --> CreateBaseNode["Create base node<br/>- id, label, parentId<br/>- cssStyles, cssClasses<br/>- shape, domId, tooltip"]
|
||||||
|
NodeCreation --> GetCompiledStyles["getCompiledStyles(classDefs)"]
|
||||||
|
NodeCreation --> GetTypeFromVertex["getTypeFromVertex(vertex)"]
|
||||||
|
|
||||||
|
%% Rendering Phase
|
||||||
|
Renderer --> flowRendererV3["flowRenderer-v3-unified.ts<br/>draw(text, id, version, diag)"]
|
||||||
|
|
||||||
|
flowRendererV3 --> RenderInit["Initialize rendering<br/>- getConfig()<br/>- handle securityLevel<br/>- getDiagramElement()"]
|
||||||
|
|
||||||
|
RenderInit --> GetLayoutData["diag.db.getData()<br/>as LayoutData"]
|
||||||
|
GetLayoutData --> SetupLayoutData["Setup layout data<br/>- type, layoutAlgorithm<br/>- direction, spacing<br/>- markers, diagramId"]
|
||||||
|
|
||||||
|
SetupLayoutData --> CallRender["render(data4Layout, svg)"]
|
||||||
|
CallRender --> SetupViewPort["setupViewPortForSVG(svg, padding)"]
|
||||||
|
SetupViewPort --> ProcessLinks["Process vertex links<br/>- create anchor elements<br/>- handle click events"]
|
||||||
|
|
||||||
|
%% Shape Rendering
|
||||||
|
CallRender --> ShapeSystem["flowChartShapes.js<br/>Shape Functions"]
|
||||||
|
|
||||||
|
ShapeSystem --> ShapeFunctions{Shape Functions}
|
||||||
|
ShapeFunctions --> question["question(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> hexagon["hexagon(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> rect_left_inv_arrow["rect_left_inv_arrow(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> lean_right["lean_right(parent, bbox, node)"]
|
||||||
|
ShapeFunctions --> lean_left["lean_left(parent, bbox, node)"]
|
||||||
|
|
||||||
|
ShapeFunctions --> insertPolygonShape["insertPolygonShape(parent, w, h, points)"]
|
||||||
|
ShapeFunctions --> intersectPolygon["intersectPolygon(node, points, point)"]
|
||||||
|
ShapeFunctions --> intersectRect["intersectRect(node, point)"]
|
||||||
|
|
||||||
|
%% Styling System
|
||||||
|
Styles --> stylesTS["styles.ts<br/>getStyles(options)"]
|
||||||
|
stylesTS --> StyleOptions["FlowChartStyleOptions<br/>- arrowheadColor, border2<br/>- clusterBkg, mainBkg<br/>- fontFamily, textColor"]
|
||||||
|
|
||||||
|
StyleOptions --> GenerateCSS["Generate CSS styles<br/>- .label, .cluster-label<br/>- .node, .edgePath<br/>- .flowchart-link, .edgeLabel"]
|
||||||
|
GenerateCSS --> GetIconStyles["getIconStyles()"]
|
||||||
|
|
||||||
|
%% Type System
|
||||||
|
Parser --> TypeSystem["types.ts<br/>Type Definitions"]
|
||||||
|
TypeSystem --> FlowVertex["FlowVertex interface"]
|
||||||
|
TypeSystem --> FlowEdge["FlowEdge interface"]
|
||||||
|
TypeSystem --> FlowClass["FlowClass interface"]
|
||||||
|
TypeSystem --> FlowSubGraph["FlowSubGraph interface"]
|
||||||
|
TypeSystem --> FlowVertexTypeParam["FlowVertexTypeParam<br/>Shape types"]
|
||||||
|
|
||||||
|
%% Utility Functions
|
||||||
|
DBMethods --> UtilityFunctions{Utility Functions}
|
||||||
|
UtilityFunctions --> lookUpDomId["lookUpDomId(id)"]
|
||||||
|
UtilityFunctions --> getClasses["getClasses()"]
|
||||||
|
UtilityFunctions --> getDirection["getDirection()"]
|
||||||
|
UtilityFunctions --> getVertices["getVertices()"]
|
||||||
|
UtilityFunctions --> getEdges["getEdges()"]
|
||||||
|
UtilityFunctions --> getSubGraphs["getSubGraphs()"]
|
||||||
|
UtilityFunctions --> clear["clear()"]
|
||||||
|
UtilityFunctions --> defaultConfig["defaultConfig()"]
|
||||||
|
|
||||||
|
%% Event Handling
|
||||||
|
ProcessLinks --> EventHandling{Event Handling}
|
||||||
|
EventHandling --> setupToolTips["setupToolTips(element)"]
|
||||||
|
EventHandling --> bindFunctions["bindFunctions(element)"]
|
||||||
|
EventHandling --> runFunc["utils.runFunc(functionName, args)"]
|
||||||
|
|
||||||
|
%% Common Database Functions
|
||||||
|
DBMethods --> CommonDB["commonDb.js functions"]
|
||||||
|
CommonDB --> setAccTitle["setAccTitle()"]
|
||||||
|
CommonDB --> getAccTitle["getAccTitle()"]
|
||||||
|
CommonDB --> setAccDescription["setAccDescription()"]
|
||||||
|
CommonDB --> getAccDescription["getAccDescription()"]
|
||||||
|
CommonDB --> setDiagramTitle["setDiagramTitle()"]
|
||||||
|
CommonDB --> getDiagramTitle["getDiagramTitle()"]
|
||||||
|
CommonDB --> commonClear["clear()"]
|
||||||
|
|
||||||
|
%% Final Output
|
||||||
|
ProcessLinks --> FinalSVG["Final SVG Output"]
|
||||||
|
|
||||||
|
%% Layout Algorithm Selection
|
||||||
|
SetupLayoutData --> LayoutAlgorithm{Layout Algorithm}
|
||||||
|
LayoutAlgorithm --> Dagre["dagre<br/>(default)"]
|
||||||
|
LayoutAlgorithm --> DagreWrapper["dagre-wrapper<br/>(v2 renderer)"]
|
||||||
|
LayoutAlgorithm --> ELK["elk<br/>(external package)"]
|
||||||
|
|
||||||
|
%% Testing Components
|
||||||
|
FlowDBClass --> TestFiles["Test Files"]
|
||||||
|
TestFiles --> flowDbSpec["flowDb.spec.ts"]
|
||||||
|
TestFiles --> flowChartShapesSpec["flowChartShapes.spec.js"]
|
||||||
|
TestFiles --> ParserTests["parser/*.spec.js files<br/>- flow-text.spec.js<br/>- flow-edges.spec.js<br/>- flow-style.spec.js<br/>- subgraph.spec.js"]
|
||||||
|
|
||||||
|
%% Configuration
|
||||||
|
Init --> ConfigSetup["Configuration Setup"]
|
||||||
|
ConfigSetup --> FlowchartConfig["cnf.flowchart config"]
|
||||||
|
ConfigSetup --> ArrowMarkers["arrowMarkerAbsolute"]
|
||||||
|
ConfigSetup --> LayoutConfig["layout config"]
|
||||||
|
ConfigSetup --> SetConfig["setConfig() calls"]
|
307
packages/mermaid/src/docs/diagrams/mermaid-api-sequence.mmd
Normal file
307
packages/mermaid/src/docs/diagrams/mermaid-api-sequence.mmd
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/mermaidAPI.ts"
|
||||||
|
- "File: /packages/mermaid/src/mermaid.ts"
|
||||||
|
generationTime: 2025-01-28T16:30:00.000Z
|
||||||
|
---
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as User/Browser
|
||||||
|
participant Mermaid as mermaid.ts
|
||||||
|
participant Queue as executionQueue
|
||||||
|
participant API as mermaidAPI.ts
|
||||||
|
participant Config as configApi
|
||||||
|
participant Preprocessor as preprocessDiagram
|
||||||
|
participant DiagramAPI as diagram-api
|
||||||
|
participant Diagram as Diagram.fromText
|
||||||
|
participant Renderer as diagram.renderer
|
||||||
|
participant Styles as Styling System
|
||||||
|
participant DOM as DOM/SVG
|
||||||
|
|
||||||
|
Note over User, DOM: Mermaid Complete API Flow
|
||||||
|
|
||||||
|
%% Initialization Phase
|
||||||
|
User->>+Mermaid: mermaid.initialize(config)
|
||||||
|
Mermaid->>+API: mermaidAPI.initialize(config)
|
||||||
|
|
||||||
|
API->>API: assignWithDepth({}, userOptions)
|
||||||
|
API->>API: handle legacy fontFamily config
|
||||||
|
API->>Config: saveConfigFromInitialize(options)
|
||||||
|
|
||||||
|
alt Theme Configuration Available
|
||||||
|
API->>API: check if theme in theme object
|
||||||
|
API->>API: set themeVariables from theme
|
||||||
|
else Default Theme
|
||||||
|
API->>API: use default theme variables
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>Config: setSiteConfig(options) or getSiteConfig()
|
||||||
|
API->>API: setLogLevel(config.logLevel)
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
|
||||||
|
API-->>-Mermaid: initialization complete
|
||||||
|
Mermaid-->>-User: ready to render
|
||||||
|
|
||||||
|
%% Content Loaded Event
|
||||||
|
User->>DOM: document.load event
|
||||||
|
DOM->>+Mermaid: contentLoaded()
|
||||||
|
|
||||||
|
opt startOnLoad is true
|
||||||
|
Mermaid->>Config: getConfig()
|
||||||
|
Config-->>Mermaid: { startOnLoad: true }
|
||||||
|
Mermaid->>Mermaid: run()
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-DOM: event handling complete
|
||||||
|
|
||||||
|
%% Main Run Function
|
||||||
|
User->>+Mermaid: mermaid.run(options)
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: runThrowsErrors(options)
|
||||||
|
Mermaid->>Config: getConfig()
|
||||||
|
Config-->>Mermaid: configuration object
|
||||||
|
|
||||||
|
alt nodes provided
|
||||||
|
Mermaid->>Mermaid: use provided nodes
|
||||||
|
else querySelector provided
|
||||||
|
Mermaid->>DOM: document.querySelectorAll(querySelector)
|
||||||
|
DOM-->>Mermaid: nodesToProcess
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: new InitIDGenerator(deterministicIds, seed)
|
||||||
|
|
||||||
|
loop For each diagram element
|
||||||
|
Mermaid->>DOM: check element.getAttribute('data-processed')
|
||||||
|
|
||||||
|
opt not processed
|
||||||
|
Mermaid->>DOM: element.setAttribute('data-processed', 'true')
|
||||||
|
Mermaid->>Mermaid: generate unique id
|
||||||
|
Mermaid->>DOM: get element.innerHTML
|
||||||
|
Mermaid->>Mermaid: entityDecode and clean text
|
||||||
|
Mermaid->>Mermaid: detectInit(txt)
|
||||||
|
|
||||||
|
Mermaid->>Queue: render(id, txt, element)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: processing initiated
|
||||||
|
|
||||||
|
%% Render Function (Queued)
|
||||||
|
activate Queue
|
||||||
|
Queue->>+API: mermaidAPI.render(id, text, container)
|
||||||
|
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
API->>+Preprocessor: processAndSetConfigs(text)
|
||||||
|
|
||||||
|
Preprocessor->>Preprocessor: preprocessDiagram(text)
|
||||||
|
Preprocessor->>Config: reset()
|
||||||
|
Preprocessor->>Config: addDirective(processed.config)
|
||||||
|
Preprocessor-->>-API: { code, config }
|
||||||
|
|
||||||
|
API->>Config: getConfig()
|
||||||
|
Config-->>API: current configuration
|
||||||
|
|
||||||
|
opt text length > maxTextSize
|
||||||
|
API->>API: text = MAX_TEXTLENGTH_EXCEEDED_MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: setup id selectors and element IDs
|
||||||
|
API->>API: determine security level (sandbox/loose)
|
||||||
|
|
||||||
|
%% DOM Setup
|
||||||
|
alt svgContainingElement provided
|
||||||
|
alt isSandboxed
|
||||||
|
API->>DOM: sandboxedIframe(select(svgContainingElement), iFrameID)
|
||||||
|
API->>DOM: select iframe contentDocument body
|
||||||
|
else
|
||||||
|
API->>DOM: select(svgContainingElement)
|
||||||
|
end
|
||||||
|
else no container
|
||||||
|
API->>API: removeExistingElements(document, id, divId, iFrameId)
|
||||||
|
alt isSandboxed
|
||||||
|
API->>DOM: sandboxedIframe(select('body'), iFrameID)
|
||||||
|
else
|
||||||
|
API->>DOM: select('body')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>DOM: appendDivSvgG(root, id, enclosingDivID, fontFamily, XMLNS_XLINK_STD)
|
||||||
|
|
||||||
|
%% Diagram Creation
|
||||||
|
API->>+Diagram: Diagram.fromText(text, { title: processed.title })
|
||||||
|
|
||||||
|
Diagram->>DiagramAPI: detect diagram type
|
||||||
|
Diagram->>DiagramAPI: load appropriate diagram
|
||||||
|
Diagram-->>-API: diagram instance
|
||||||
|
|
||||||
|
opt parsing error occurred
|
||||||
|
API->>+Diagram: Diagram.fromText('error')
|
||||||
|
Diagram-->>-API: error diagram
|
||||||
|
API->>API: store parseEncounteredException
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Style Generation
|
||||||
|
API->>DOM: get svg element and firstChild
|
||||||
|
API->>Renderer: diag.renderer.getClasses(text, diag)
|
||||||
|
Renderer-->>API: diagramClassDefs
|
||||||
|
|
||||||
|
API->>+Styles: createUserStyles(config, diagramType, diagramClassDefs, idSelector)
|
||||||
|
|
||||||
|
Styles->>Styles: createCssStyles(config, classDefs)
|
||||||
|
|
||||||
|
opt config.themeCSS defined
|
||||||
|
Styles->>Styles: append themeCSS
|
||||||
|
end
|
||||||
|
|
||||||
|
opt fontFamily configured
|
||||||
|
Styles->>Styles: add CSS variables for fonts
|
||||||
|
end
|
||||||
|
|
||||||
|
opt classDefs exist
|
||||||
|
loop For each styleClassDef
|
||||||
|
opt has styles
|
||||||
|
Styles->>Styles: cssImportantStyles for each CSS element
|
||||||
|
end
|
||||||
|
opt has textStyles
|
||||||
|
Styles->>Styles: cssImportantStyles for tspan elements
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Styles->>Styles: getStyles(graphType, userCSSstyles, themeVariables)
|
||||||
|
Styles->>Styles: serialize(compile(svgId{allStyles}), stringify)
|
||||||
|
Styles-->>-API: compiled CSS rules
|
||||||
|
|
||||||
|
API->>DOM: create style element
|
||||||
|
API->>DOM: style.innerHTML = rules
|
||||||
|
API->>DOM: svg.insertBefore(style, firstChild)
|
||||||
|
|
||||||
|
%% Diagram Rendering
|
||||||
|
API->>+Renderer: diag.renderer.draw(text, id, version, diag)
|
||||||
|
|
||||||
|
Renderer->>Renderer: diagram-specific rendering logic
|
||||||
|
Renderer->>DOM: create SVG elements
|
||||||
|
Renderer->>DOM: apply positioning and styling
|
||||||
|
Renderer-->>-API: rendered diagram
|
||||||
|
|
||||||
|
opt rendering error
|
||||||
|
alt suppressErrorRendering
|
||||||
|
API->>API: removeTempElements()
|
||||||
|
API->>Mermaid: throw error
|
||||||
|
else
|
||||||
|
API->>Renderer: errorRenderer.draw(text, id, version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Accessibility and Cleanup
|
||||||
|
API->>DOM: select svg element
|
||||||
|
API->>Diagram: diag.db.getAccTitle()
|
||||||
|
API->>Diagram: diag.db.getAccDescription()
|
||||||
|
API->>API: addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr)
|
||||||
|
|
||||||
|
API->>DOM: set xmlns for foreignobject elements
|
||||||
|
API->>DOM: get innerHTML from enclosing div
|
||||||
|
|
||||||
|
API->>+API: cleanUpSvgCode(svgCode, isSandboxed, arrowMarkerAbsolute)
|
||||||
|
|
||||||
|
opt not useArrowMarkerUrls and not sandboxed
|
||||||
|
API->>API: replace marker-end URLs with anchors
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: decodeEntities(svgCode)
|
||||||
|
API->>API: replace <br> with <br/>
|
||||||
|
API-->>-API: cleaned SVG code
|
||||||
|
|
||||||
|
alt isSandboxed
|
||||||
|
API->>+API: putIntoIFrame(svgCode, svgEl)
|
||||||
|
API->>API: calculate iframe height
|
||||||
|
API->>API: toBase64 encode SVG content
|
||||||
|
API->>API: create iframe with sandbox attributes
|
||||||
|
API-->>-API: iframe HTML
|
||||||
|
else not loose security
|
||||||
|
API->>API: DOMPurify.sanitize(svgCode, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
API->>API: attachFunctions()
|
||||||
|
API->>API: removeTempElements()
|
||||||
|
|
||||||
|
opt parseEncounteredException
|
||||||
|
API->>Mermaid: throw parseEncounteredException
|
||||||
|
end
|
||||||
|
|
||||||
|
API-->>-Queue: { diagramType, svg: svgCode, bindFunctions }
|
||||||
|
|
||||||
|
%% Return to Web Integration
|
||||||
|
activate Mermaid
|
||||||
|
Queue-->>Mermaid: render result
|
||||||
|
Mermaid->>DOM: element.innerHTML = svg
|
||||||
|
|
||||||
|
opt postRenderCallback
|
||||||
|
Mermaid->>User: postRenderCallback(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
opt bindFunctions exist
|
||||||
|
Mermaid->>DOM: bindFunctions(element)
|
||||||
|
end
|
||||||
|
deactivate Mermaid
|
||||||
|
|
||||||
|
%% Parse Function Flow
|
||||||
|
User->>+Mermaid: mermaid.parse(text, parseOptions)
|
||||||
|
activate Queue
|
||||||
|
|
||||||
|
Queue->>+API: mermaidAPI.parse(text, parseOptions)
|
||||||
|
|
||||||
|
API->>DiagramAPI: addDiagrams()
|
||||||
|
API->>Preprocessor: processAndSetConfigs(text)
|
||||||
|
Preprocessor-->>API: { code, config }
|
||||||
|
API->>Diagram: getDiagramFromText(code)
|
||||||
|
Diagram-->>API: diagram instance
|
||||||
|
API-->>-Queue: { diagramType: diagram.type, config }
|
||||||
|
|
||||||
|
Queue-->>-Mermaid: parse result
|
||||||
|
Mermaid-->>-User: ParseResult or false
|
||||||
|
|
||||||
|
%% External Diagram Registration
|
||||||
|
User->>+Mermaid: registerExternalDiagrams(diagrams, options)
|
||||||
|
|
||||||
|
Mermaid->>DiagramAPI: addDiagrams()
|
||||||
|
Mermaid->>DiagramAPI: registerLazyLoadedDiagrams(...diagrams)
|
||||||
|
|
||||||
|
opt lazyLoad is false
|
||||||
|
Mermaid->>DiagramAPI: loadRegisteredDiagrams()
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: registration complete
|
||||||
|
|
||||||
|
%% Error Handling
|
||||||
|
Note over Mermaid, API: Error Handling Throughout
|
||||||
|
alt Error occurs
|
||||||
|
API->>Mermaid: throw error
|
||||||
|
Mermaid->>+Mermaid: handleError(error, errors, parseError)
|
||||||
|
|
||||||
|
Mermaid->>Mermaid: log.warn(error)
|
||||||
|
|
||||||
|
alt isDetailedError
|
||||||
|
Mermaid->>User: parseError(error.str, error.hash)
|
||||||
|
else
|
||||||
|
Mermaid->>User: parseError(error)
|
||||||
|
end
|
||||||
|
|
||||||
|
opt not suppressErrors
|
||||||
|
Mermaid->>User: throw error
|
||||||
|
end
|
||||||
|
|
||||||
|
Mermaid-->>-User: error handled
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Configuration Details
|
||||||
|
Note over Config: Configuration Functions
|
||||||
|
Note right of Config: Functions:<br/>- reset()<br/>- getConfig()<br/>- setConfig()<br/>- getSiteConfig()<br/>- updateSiteConfig()<br/>- saveConfigFromInitialize()
|
||||||
|
|
||||||
|
Note over Styles: CSS Generation
|
||||||
|
Note right of Styles: Features:<br/>- createCssStyles()<br/>- createUserStyles()<br/>- cssImportantStyles()<br/>- Theme integration<br/>- Class definitions
|
||||||
|
|
||||||
|
Note over API: Security Levels
|
||||||
|
Note right of API: Modes:<br/>- sandbox: iframe isolation<br/>- loose: minimal sanitization<br/>- default: DOMPurify sanitization
|
||||||
|
|
||||||
|
Note over API: Helper Functions
|
||||||
|
Note right of API: Utilities:<br/>- cleanUpSvgCode()<br/>- putIntoIFrame()<br/>- appendDivSvgG()<br/>- removeExistingElements()
|
@@ -0,0 +1,180 @@
|
|||||||
|
---
|
||||||
|
references:
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapDb.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/detector.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/styles.ts"
|
||||||
|
- "File: /packages/mermaid/src/diagrams/mindmap/svgDraw.ts"
|
||||||
|
generationTime: 2025-01-28T16:00:00.000Z
|
||||||
|
---
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as User Input Text
|
||||||
|
participant Detector as detector.ts
|
||||||
|
participant Loader as DiagramLoader
|
||||||
|
participant Definition as mindmap-definition.ts
|
||||||
|
participant Parser as parser/mindmap.jison
|
||||||
|
participant DB as MindmapDB
|
||||||
|
participant Renderer as mindmapRenderer.ts
|
||||||
|
participant Cytoscape as cytoscape.js
|
||||||
|
participant SVGDraw as svgDraw.ts
|
||||||
|
participant Styles as styles.ts
|
||||||
|
participant Output as Final SVG
|
||||||
|
|
||||||
|
Note over User, Output: Mindmap Implementation Flow
|
||||||
|
|
||||||
|
%% Detection Phase
|
||||||
|
User->>Detector: /^\s*mindmap/ text input
|
||||||
|
activate Detector
|
||||||
|
Detector->>Detector: detector(txt) validates pattern
|
||||||
|
Detector->>Loader: loader() function called
|
||||||
|
deactivate Detector
|
||||||
|
|
||||||
|
activate Loader
|
||||||
|
Loader->>Definition: import mindmap-definition.js
|
||||||
|
deactivate Loader
|
||||||
|
|
||||||
|
%% Core Structure Setup
|
||||||
|
activate Definition
|
||||||
|
Definition->>DB: get db() → new MindmapDB()
|
||||||
|
Definition->>Renderer: setup renderer
|
||||||
|
Definition->>Parser: setup parser
|
||||||
|
Definition->>Styles: setup styles
|
||||||
|
deactivate Definition
|
||||||
|
|
||||||
|
%% Database Initialization
|
||||||
|
activate DB
|
||||||
|
Note over DB: MindmapDB Constructor
|
||||||
|
DB->>DB: initialize nodes array
|
||||||
|
DB->>DB: setup nodeType constants
|
||||||
|
DB->>DB: bind methods
|
||||||
|
DB->>DB: clear() state
|
||||||
|
|
||||||
|
%% Parsing Phase
|
||||||
|
activate Parser
|
||||||
|
User->>Parser: mindmap syntax text
|
||||||
|
|
||||||
|
loop For each node in hierarchy
|
||||||
|
Parser->>DB: addNode(level, id, descr, type)
|
||||||
|
activate DB
|
||||||
|
DB->>DB: sanitizeText(id, descr)
|
||||||
|
DB->>DB: getType(startStr, endStr)
|
||||||
|
Note right of DB: Shape Detection:<br/>[ → RECT<br/>( → ROUNDED_RECT<br/>(( → CIRCLE<br/>)) → BANG<br/>{{ → HEXAGON
|
||||||
|
DB->>DB: getParent(level)
|
||||||
|
DB->>DB: create MindmapNode
|
||||||
|
DB->>DB: add to hierarchy
|
||||||
|
deactivate DB
|
||||||
|
end
|
||||||
|
|
||||||
|
opt Icon/Class Decoration
|
||||||
|
Parser->>DB: decorateNode(decoration)
|
||||||
|
DB->>DB: set icon/class properties
|
||||||
|
end
|
||||||
|
deactivate Parser
|
||||||
|
|
||||||
|
%% Data Preparation
|
||||||
|
Renderer->>DB: getData() for layout
|
||||||
|
activate DB
|
||||||
|
DB->>DB: collect all nodes
|
||||||
|
DB->>DB: build parent-child relationships
|
||||||
|
DB-->>Renderer: return node hierarchy
|
||||||
|
deactivate DB
|
||||||
|
|
||||||
|
%% Rendering Pipeline
|
||||||
|
activate Renderer
|
||||||
|
Note over Renderer: Rendering Phase
|
||||||
|
|
||||||
|
Renderer->>Cytoscape: initialize cytoscape
|
||||||
|
activate Cytoscape
|
||||||
|
|
||||||
|
loop For each node in mindmap
|
||||||
|
Renderer->>Cytoscape: addNodes(mindmap, cy, conf, level)
|
||||||
|
Cytoscape->>Cytoscape: create node data
|
||||||
|
Cytoscape->>Cytoscape: set position (x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
loop For parent-child relationships
|
||||||
|
Renderer->>Cytoscape: add edges
|
||||||
|
Cytoscape->>Cytoscape: create edge data
|
||||||
|
end
|
||||||
|
|
||||||
|
Renderer->>Cytoscape: configure cose-bilkent layout
|
||||||
|
Cytoscape->>Cytoscape: calculate optimal positions
|
||||||
|
Cytoscape-->>Renderer: return positioned graph
|
||||||
|
deactivate Cytoscape
|
||||||
|
|
||||||
|
%% SVG Generation
|
||||||
|
Renderer->>SVGDraw: drawNodes(db, svg, mindmap, section, conf)
|
||||||
|
activate SVGDraw
|
||||||
|
|
||||||
|
loop For each node recursively
|
||||||
|
SVGDraw->>SVGDraw: select shape function
|
||||||
|
|
||||||
|
alt Default Shape
|
||||||
|
SVGDraw->>SVGDraw: defaultBkg() - rounded rectangle
|
||||||
|
else Rectangle Shape
|
||||||
|
SVGDraw->>SVGDraw: rectBkg() - sharp corners
|
||||||
|
else Circle Shape
|
||||||
|
SVGDraw->>SVGDraw: circleBkg() - perfect circle
|
||||||
|
else Cloud Shape
|
||||||
|
SVGDraw->>SVGDraw: cloudBkg() - organic curves
|
||||||
|
else Bang Shape
|
||||||
|
SVGDraw->>SVGDraw: bangBkg() - explosion style
|
||||||
|
else Hexagon Shape
|
||||||
|
SVGDraw->>SVGDraw: hexagonBkg() - six sides
|
||||||
|
end
|
||||||
|
|
||||||
|
SVGDraw->>SVGDraw: create SVG elements
|
||||||
|
SVGDraw->>SVGDraw: add text labels
|
||||||
|
SVGDraw->>SVGDraw: position node
|
||||||
|
|
||||||
|
opt Node has children
|
||||||
|
SVGDraw->>SVGDraw: drawNodes() recursive call
|
||||||
|
end
|
||||||
|
end
|
||||||
|
deactivate SVGDraw
|
||||||
|
|
||||||
|
%% Edge Rendering
|
||||||
|
Renderer->>Renderer: drawEdges(edgesEl, cy)
|
||||||
|
loop For each edge
|
||||||
|
Renderer->>Renderer: extract edge bounds
|
||||||
|
Renderer->>Renderer: draw SVG path
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Styling Application
|
||||||
|
Renderer->>Styles: getStyles(options)
|
||||||
|
activate Styles
|
||||||
|
|
||||||
|
Styles->>Styles: genSections(options)
|
||||||
|
loop For THEME_COLOR_LIMIT sections
|
||||||
|
Styles->>Styles: generate color scale
|
||||||
|
Styles->>Styles: create CSS rules
|
||||||
|
Note right of Styles: .section-X fills<br/>.edge-depth-X widths<br/>.node-icon-X colors
|
||||||
|
end
|
||||||
|
|
||||||
|
Styles->>Styles: apply theme integration
|
||||||
|
Styles-->>Renderer: return compiled CSS
|
||||||
|
deactivate Styles
|
||||||
|
|
||||||
|
%% Final Assembly
|
||||||
|
Renderer->>Output: selectSvgElement()
|
||||||
|
Renderer->>Output: setupGraphViewbox()
|
||||||
|
Renderer->>Output: apply styles
|
||||||
|
Renderer->>Output: add interactive elements
|
||||||
|
deactivate Renderer
|
||||||
|
|
||||||
|
activate Output
|
||||||
|
Note over Output: Final Mindmap Features
|
||||||
|
Output->>Output: responsive layout
|
||||||
|
Output->>Output: accessibility attributes
|
||||||
|
Output->>Output: hover effects
|
||||||
|
Output->>Output: click handling
|
||||||
|
Output-->>User: rendered mindmap
|
||||||
|
deactivate Output
|
||||||
|
|
||||||
|
%% Configuration Details
|
||||||
|
Note over DB, Styles: Configuration Options
|
||||||
|
Note right of DB: Padding Calculations:<br/>Base padding from config<br/>RECT: ×2 padding<br/>ROUNDED_RECT: ×2 padding<br/>HEXAGON: ×2 padding
|
||||||
|
Note right of Styles: Section Management:<br/>MAX_SECTIONS = 12<br/>Dynamic color generation<br/>Git theme integration
|
||||||
|
Note right of Renderer: Layout Parameters:<br/>Cytoscape configuration<br/>coseBilkent settings<br/>Node spacing rules
|
@@ -54,7 +54,7 @@ export async function requirementBox<T extends SVGGraphicsElement>(
|
|||||||
if (isRequirementNode) {
|
if (isRequirementNode) {
|
||||||
const idHeight = await addText(
|
const idHeight = await addText(
|
||||||
shapeSvg,
|
shapeSvg,
|
||||||
`${requirementNode.requirementId ? `id: ${requirementNode.requirementId}` : ''}`,
|
`${requirementNode.requirementId ? `ID: ${requirementNode.requirementId}` : ''}`,
|
||||||
accumulativeHeight,
|
accumulativeHeight,
|
||||||
node.labelStyle
|
node.labelStyle
|
||||||
);
|
);
|
||||||
|
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
@@ -116,10 +116,10 @@ importers:
|
|||||||
specifier: ^8.1.3
|
specifier: ^8.1.3
|
||||||
version: 8.1.3
|
version: 8.1.3
|
||||||
eslint-plugin-jest:
|
eslint-plugin-jest:
|
||||||
specifier: ^28.11.2
|
specifier: ^28.14.0
|
||||||
version: 28.14.0(@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(jest@30.0.4(@types/node@22.13.5))(typescript@5.7.3)
|
version: 28.14.0(@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(jest@30.0.4(@types/node@22.13.5))(typescript@5.7.3)
|
||||||
eslint-plugin-jsdoc:
|
eslint-plugin-jsdoc:
|
||||||
specifier: ^50.6.17
|
specifier: ^50.8.0
|
||||||
version: 50.8.0(eslint@9.26.0(jiti@2.4.2))
|
version: 50.8.0(eslint@9.26.0(jiti@2.4.2))
|
||||||
eslint-plugin-json:
|
eslint-plugin-json:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
@@ -203,7 +203,7 @@ importers:
|
|||||||
specifier: ~5.7.3
|
specifier: ~5.7.3
|
||||||
version: 5.7.3
|
version: 5.7.3
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
specifier: ^8.32.1
|
specifier: ^8.38.0
|
||||||
version: 8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
version: 8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
||||||
vite:
|
vite:
|
||||||
specifier: ^7.0.3
|
specifier: ^7.0.3
|
||||||
@@ -3485,10 +3485,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <5.9.0'
|
typescript: '>=4.8.4 <5.9.0'
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.32.0':
|
|
||||||
resolution: {integrity: sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==}
|
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.38.0':
|
'@typescript-eslint/scope-manager@8.38.0':
|
||||||
resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==}
|
resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -3510,10 +3506,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
|
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
|
||||||
engines: {node: ^18.18.0 || >=20.0.0}
|
engines: {node: ^18.18.0 || >=20.0.0}
|
||||||
|
|
||||||
'@typescript-eslint/types@8.32.0':
|
|
||||||
resolution: {integrity: sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==}
|
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
||||||
|
|
||||||
'@typescript-eslint/types@8.38.0':
|
'@typescript-eslint/types@8.38.0':
|
||||||
resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==}
|
resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -3527,25 +3519,12 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.32.0':
|
|
||||||
resolution: {integrity: sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==}
|
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
||||||
peerDependencies:
|
|
||||||
typescript: '>=4.8.4 <5.9.0'
|
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.38.0':
|
'@typescript-eslint/typescript-estree@8.38.0':
|
||||||
resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==}
|
resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4 <5.9.0'
|
typescript: '>=4.8.4 <5.9.0'
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.32.0':
|
|
||||||
resolution: {integrity: sha512-8S9hXau6nQ/sYVtC3D6ISIDoJzS1NsCK+gluVhLN2YkBPX+/1wkwyUiDKnxRh15579WoOIyVWnoyIf3yGI9REw==}
|
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
||||||
peerDependencies:
|
|
||||||
eslint: ^8.57.0 || ^9.0.0
|
|
||||||
typescript: '>=4.8.4 <5.9.0'
|
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.38.0':
|
'@typescript-eslint/utils@8.38.0':
|
||||||
resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==}
|
resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -3557,10 +3536,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
|
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
|
||||||
engines: {node: ^18.18.0 || >=20.0.0}
|
engines: {node: ^18.18.0 || >=20.0.0}
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.32.0':
|
|
||||||
resolution: {integrity: sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==}
|
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.38.0':
|
'@typescript-eslint/visitor-keys@8.38.0':
|
||||||
resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==}
|
resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -12777,7 +12752,7 @@ snapshots:
|
|||||||
'@es-joy/jsdoccomment@0.50.2':
|
'@es-joy/jsdoccomment@0.50.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.7
|
'@types/estree': 1.0.7
|
||||||
'@typescript-eslint/types': 8.32.0
|
'@typescript-eslint/types': 8.38.0
|
||||||
comment-parser: 1.4.1
|
comment-parser: 1.4.1
|
||||||
esquery: 1.6.0
|
esquery: 1.6.0
|
||||||
jsdoc-type-pratt-parser: 4.1.0
|
jsdoc-type-pratt-parser: 4.1.0
|
||||||
@@ -14320,11 +14295,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.32.0':
|
|
||||||
dependencies:
|
|
||||||
'@typescript-eslint/types': 8.32.0
|
|
||||||
'@typescript-eslint/visitor-keys': 8.32.0
|
|
||||||
|
|
||||||
'@typescript-eslint/scope-manager@8.38.0':
|
'@typescript-eslint/scope-manager@8.38.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.38.0
|
'@typescript-eslint/types': 8.38.0
|
||||||
@@ -14348,8 +14318,6 @@ snapshots:
|
|||||||
|
|
||||||
'@typescript-eslint/types@7.18.0': {}
|
'@typescript-eslint/types@7.18.0': {}
|
||||||
|
|
||||||
'@typescript-eslint/types@8.32.0': {}
|
|
||||||
|
|
||||||
'@typescript-eslint/types@8.38.0': {}
|
'@typescript-eslint/types@8.38.0': {}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.7.3)':
|
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.7.3)':
|
||||||
@@ -14367,20 +14335,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.32.0(typescript@5.7.3)':
|
|
||||||
dependencies:
|
|
||||||
'@typescript-eslint/types': 8.32.0
|
|
||||||
'@typescript-eslint/visitor-keys': 8.32.0
|
|
||||||
debug: 4.4.1(supports-color@8.1.1)
|
|
||||||
fast-glob: 3.3.3
|
|
||||||
is-glob: 4.0.3
|
|
||||||
minimatch: 9.0.5
|
|
||||||
semver: 7.7.2
|
|
||||||
ts-api-utils: 2.1.0(typescript@5.7.3)
|
|
||||||
typescript: 5.7.3
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.38.0(typescript@5.7.3)':
|
'@typescript-eslint/typescript-estree@8.38.0(typescript@5.7.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.38.0(typescript@5.7.3)
|
'@typescript-eslint/project-service': 8.38.0(typescript@5.7.3)
|
||||||
@@ -14397,17 +14351,6 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.32.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)':
|
|
||||||
dependencies:
|
|
||||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0(jiti@2.4.2))
|
|
||||||
'@typescript-eslint/scope-manager': 8.32.0
|
|
||||||
'@typescript-eslint/types': 8.32.0
|
|
||||||
'@typescript-eslint/typescript-estree': 8.32.0(typescript@5.7.3)
|
|
||||||
eslint: 9.26.0(jiti@2.4.2)
|
|
||||||
typescript: 5.7.3
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)':
|
'@typescript-eslint/utils@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0(jiti@2.4.2))
|
'@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0(jiti@2.4.2))
|
||||||
@@ -14424,11 +14367,6 @@ snapshots:
|
|||||||
'@typescript-eslint/types': 7.18.0
|
'@typescript-eslint/types': 7.18.0
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.32.0':
|
|
||||||
dependencies:
|
|
||||||
'@typescript-eslint/types': 8.32.0
|
|
||||||
eslint-visitor-keys: 4.2.0
|
|
||||||
|
|
||||||
'@typescript-eslint/visitor-keys@8.38.0':
|
'@typescript-eslint/visitor-keys@8.38.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.38.0
|
'@typescript-eslint/types': 8.38.0
|
||||||
@@ -16956,7 +16894,7 @@ snapshots:
|
|||||||
|
|
||||||
eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(jest@30.0.4(@types/node@22.13.5))(typescript@5.7.3):
|
eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(jest@30.0.4(@types/node@22.13.5))(typescript@5.7.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/utils': 8.32.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
'@typescript-eslint/utils': 8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
||||||
eslint: 9.26.0(jiti@2.4.2)
|
eslint: 9.26.0(jiti@2.4.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
'@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.7.3)
|
||||||
|
Reference in New Issue
Block a user