@uigraph/sdk 1.2.7 → 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2564,6 +2564,7 @@ function convertC4ToReactFlow(data) {
2564
2564
  },
2565
2565
  data: {
2566
2566
  source: "mermaid",
2567
+ c4DiagramType: data.type,
2567
2568
  c4BoundaryKind: boundary.kind,
2568
2569
  boundaryType: boundary.type,
2569
2570
  description: boundary.description,
@@ -2603,6 +2604,7 @@ function convertC4ToReactFlow(data) {
2603
2604
  source: "mermaid",
2604
2605
  diagramId: element.subDiagramId,
2605
2606
  diagramName: element.label,
2607
+ c4DiagramType: data.type,
2606
2608
  c4Kind: element.kind,
2607
2609
  c4Shape: element.shape,
2608
2610
  isExternal: element.isExternal,
@@ -2666,6 +2668,9 @@ function convertC4ToReactFlow(data) {
2666
2668
  },
2667
2669
  data: {
2668
2670
  source: "mermaid",
2671
+ c4RelDirection: rel.direction,
2672
+ c4RelTechnology: rel.technology,
2673
+ c4RelDescription: rel.description,
2669
2674
  labelColor: style === null || style === void 0 ? void 0 : style.textColor,
2670
2675
  labelOffsetX: style === null || style === void 0 ? void 0 : style.offsetX,
2671
2676
  labelOffsetY: style === null || style === void 0 ? void 0 : style.offsetY
@@ -5199,31 +5204,6 @@ function _convertMermaidToReactFlow() {
5199
5204
  });
5200
5205
  return _convertMermaidToReactFlow.apply(this, arguments);
5201
5206
  }
5202
- function sanitizeMermaidLabels(src) {
5203
- if (!src) return src;
5204
- const subgraphFixed = src.replace(/([A-Za-z0-9_]+)\[((?:(?![\"']).)*?)\]/g, (m, id, label) => {
5205
- if (/^[\"']/.test(label)) return m;
5206
- if (/[()\"\[\],:;]/.test(label)) return `${id}[\"${String(label).replace(/\\/g, "\\\\").replace(/\"/g, "\\\"")}\"]`;
5207
- return m;
5208
- }).replace(/^([ \t]*subgraph\s+)([^\n\r]+)(\|[^\n\r]*)?$/gim, (m, pre, title, rest) => {
5209
- const t = String(title).trim();
5210
- if (/^[\"']/.test(t)) return m;
5211
- if (/[()\"\[\],:;]/.test(t)) return `${pre}\"${t.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"")}\"${rest || ""}`;
5212
- return m;
5213
- });
5214
- const diagRegex = /\b(graph|flowchart|sequenceDiagram|stateDiagram|classDiagram|gantt|journey|erDiagram|gitGraph|pie|timeline|infoDiagram)\b/i;
5215
- const allStarts = [];
5216
- let mm;
5217
- const globalRegex = new RegExp(diagRegex.source, "gim");
5218
- while ((mm = globalRegex.exec(subgraphFixed)) !== null) {
5219
- allStarts.push(mm.index);
5220
- if (globalRegex.lastIndex === mm.index) globalRegex.lastIndex++;
5221
- }
5222
- if (allStarts.length <= 1) return subgraphFixed;
5223
- const first = allStarts[0];
5224
- const second = allStarts[1];
5225
- return subgraphFixed.slice(first, second).trim();
5226
- }
5227
5207
  const CONTEXT_SHAPES = new Set([
5228
5208
  "rectangle",
5229
5209
  "rounded-rect",
@@ -5358,11 +5338,15 @@ function toComponentFields(value) {
5358
5338
  }
5359
5339
  function buildContextEdges(edges, nodeIdMap) {
5360
5340
  const contextEdges = {};
5341
+ const ordinals = /* @__PURE__ */ new Map();
5361
5342
  for (const edge of edges) {
5362
- var _toRecord, _toRecord2;
5343
+ var _ordinals$get, _toRecord, _toRecord2;
5363
5344
  const source = nodeIdMap.get(edge.source);
5364
5345
  const target = nodeIdMap.get(edge.target);
5365
5346
  if (!source || !target) continue;
5347
+ const pair = `${source}-${target}`;
5348
+ const ordinal = (_ordinals$get = ordinals.get(pair)) !== null && _ordinals$get !== void 0 ? _ordinals$get : 0;
5349
+ ordinals.set(pair, ordinal + 1);
5366
5350
  const edgeContext = {};
5367
5351
  const edgeType = pickString(edge.type);
5368
5352
  if (edgeType) edgeContext.type = edgeType;
@@ -5385,9 +5369,10 @@ function buildContextEdges(edges, nodeIdMap) {
5385
5369
  if (markerStart) edgeContext.markerStart = markerStart;
5386
5370
  const markerEnd = normalizeMarker(edge.markerEnd);
5387
5371
  if (markerEnd) edgeContext.markerEnd = markerEnd;
5388
- const edgeData = (_toRecord2 = toRecord(edge.data)) !== null && _toRecord2 !== void 0 ? _toRecord2 : {};
5389
- if (Object.keys(edgeData).length > 0) edgeContext.___internal = edgeData;
5390
- if (Object.keys(edgeContext).length > 0) contextEdges[`${source}-${target}`] = edgeContext;
5372
+ const edgeData$1 = (_toRecord2 = toRecord(edge.data)) !== null && _toRecord2 !== void 0 ? _toRecord2 : {};
5373
+ if (Object.keys(edgeData$1).length > 0) edgeContext.___internal = edgeData$1;
5374
+ if (Object.keys(edgeContext).length > 0) if (ordinal === 0) contextEdges[pair] = edgeContext;
5375
+ else contextEdges[`${pair}#${ordinal}`] = edgeContext;
5391
5376
  }
5392
5377
  return contextEdges;
5393
5378
  }
@@ -5412,9 +5397,9 @@ function buildContextNodes(graphNodes, nodeIdMap) {
5412
5397
  var _toRecord, _toRecord2, _pickString, _pickString2;
5413
5398
  const mappedNodeId = nodeIdMap.get(node.id);
5414
5399
  if (!mappedNodeId) continue;
5415
- const nodeData = (_toRecord = toRecord(node.data)) !== null && _toRecord !== void 0 ? _toRecord : {};
5400
+ const nodeData$1 = (_toRecord = toRecord(node.data)) !== null && _toRecord !== void 0 ? _toRecord : {};
5416
5401
  const nodeStyle = (_toRecord2 = toRecord(node.style)) !== null && _toRecord2 !== void 0 ? _toRecord2 : {};
5417
- const componentFields = Array.isArray(nodeData.componentFields) ? nodeData.componentFields.map((field) => toRecord(field)).filter((field) => field !== void 0) : [];
5402
+ const componentFields = Array.isArray(nodeData$1.componentFields) ? nodeData$1.componentFields.map((field) => toRecord(field)).filter((field) => field !== void 0) : [];
5418
5403
  const nodeContext = {};
5419
5404
  const nodeType = pickString(node.type);
5420
5405
  if (nodeType) nodeContext.type = nodeType;
@@ -5434,47 +5419,47 @@ function buildContextNodes(graphNodes, nodeIdMap) {
5434
5419
  if (nodeType === "code") {
5435
5420
  if (codeValue) nodeContext.value = codeValue;
5436
5421
  }
5437
- const src = pickString(nodeData.src);
5422
+ const src = pickString(nodeData$1.src);
5438
5423
  if (src) nodeContext.src = src;
5439
- const animatedIcon = pickString(nodeData.animatedIcon);
5424
+ const animatedIcon = pickString(nodeData$1.animatedIcon);
5440
5425
  if (animatedIcon) nodeContext.animatedIcon = animatedIcon;
5441
- const cloud = pickString(nodeData.cloud);
5426
+ const cloud = pickString(nodeData$1.cloud);
5442
5427
  if (cloud) nodeContext.cloud = cloud;
5443
- const service = pickString(nodeData.service);
5428
+ const service = pickString(nodeData$1.service);
5444
5429
  if (service) nodeContext.service = service;
5445
- const componentId = pickString(nodeData.componentId);
5430
+ const componentId = pickString(nodeData$1.componentId);
5446
5431
  if (componentId) nodeContext.componentId = componentId;
5447
- const shape = pickString(nodeData.shape);
5432
+ const shape = pickString(nodeData$1.shape);
5448
5433
  if (shape && CONTEXT_SHAPES.has(shape)) nodeContext.shape = shape;
5449
5434
  const style = {};
5450
5435
  const width = typeof node.width === "number" ? node.width : typeof nodeStyle.width === "number" ? nodeStyle.width : void 0;
5451
5436
  if (typeof width === "number") style.width = width;
5452
5437
  const height = typeof node.height === "number" ? node.height : typeof nodeStyle.height === "number" ? nodeStyle.height : void 0;
5453
5438
  if (typeof height === "number") style.height = height;
5454
- const fill = (_pickString = pickString(nodeData.fill)) !== null && _pickString !== void 0 ? _pickString : pickString(nodeStyle.fill);
5439
+ const fill = (_pickString = pickString(nodeData$1.fill)) !== null && _pickString !== void 0 ? _pickString : pickString(nodeStyle.fill);
5455
5440
  if (fill) style.fill = fill;
5456
- const stroke = (_pickString2 = pickString(nodeData.stroke)) !== null && _pickString2 !== void 0 ? _pickString2 : pickString(nodeStyle.stroke);
5441
+ const stroke = (_pickString2 = pickString(nodeData$1.stroke)) !== null && _pickString2 !== void 0 ? _pickString2 : pickString(nodeStyle.stroke);
5457
5442
  if (stroke) style.stroke = stroke;
5458
- const strokeWidth = typeof nodeData.strokeWidth === "number" ? nodeData.strokeWidth : typeof nodeStyle.strokeWidth === "number" ? nodeStyle.strokeWidth : void 0;
5443
+ const strokeWidth = typeof nodeData$1.strokeWidth === "number" ? nodeData$1.strokeWidth : typeof nodeStyle.strokeWidth === "number" ? nodeStyle.strokeWidth : void 0;
5459
5444
  if (typeof strokeWidth === "number") style.strokeWidth = strokeWidth;
5460
- const borderRadius = typeof nodeData.borderRadius === "number" ? nodeData.borderRadius : typeof nodeStyle.borderRadius === "number" ? nodeStyle.borderRadius : void 0;
5445
+ const borderRadius = typeof nodeData$1.borderRadius === "number" ? nodeData$1.borderRadius : typeof nodeStyle.borderRadius === "number" ? nodeStyle.borderRadius : void 0;
5461
5446
  if (typeof borderRadius === "number") style.borderRadius = borderRadius;
5462
- const strokeStyleFromData = pickString(nodeData.strokeStyle);
5447
+ const strokeStyleFromData = pickString(nodeData$1.strokeStyle);
5463
5448
  if (strokeStyleFromData === "solid" || strokeStyleFromData === "dashed" || strokeStyleFromData === "dotted") style.strokeStyle = strokeStyleFromData;
5464
5449
  else {
5465
5450
  const strokeStyleFromDash = parseStrokeStyle(nodeStyle.strokeDasharray);
5466
5451
  if (strokeStyleFromDash) style.strokeStyle = strokeStyleFromDash;
5467
5452
  }
5468
- const borderAnimationEnabled = typeof nodeData.borderAnimationEnabled === "boolean" ? nodeData.borderAnimationEnabled : nodeData.strokeAnimation === "dash" ? true : void 0;
5453
+ const borderAnimationEnabled = typeof nodeData$1.borderAnimationEnabled === "boolean" ? nodeData$1.borderAnimationEnabled : nodeData$1.strokeAnimation === "dash" ? true : void 0;
5469
5454
  if (typeof borderAnimationEnabled === "boolean") style.borderAnimationEnabled = borderAnimationEnabled;
5470
5455
  if (Object.keys(style).length > 0) nodeContext.style = style;
5471
- const tableColumns = Array.isArray(nodeData.columns) ? nodeData.columns.filter((value) => typeof value === "string") : void 0;
5472
- const tableRows = Array.isArray(nodeData.rows) ? nodeData.rows.map((row) => Array.isArray(row) ? row.filter((value) => typeof value === "string") : void 0).filter((row) => row !== void 0) : void 0;
5456
+ const tableColumns = Array.isArray(nodeData$1.columns) ? nodeData$1.columns.filter((value) => typeof value === "string") : void 0;
5457
+ const tableRows = Array.isArray(nodeData$1.rows) ? nodeData$1.rows.map((row) => Array.isArray(row) ? row.filter((value) => typeof value === "string") : void 0).filter((row) => row !== void 0) : void 0;
5473
5458
  if (tableColumns || tableRows) nodeContext.table = {
5474
5459
  columns: tableColumns !== null && tableColumns !== void 0 ? tableColumns : [],
5475
5460
  rows: tableRows !== null && tableRows !== void 0 ? tableRows : []
5476
5461
  };
5477
- const serviceTable = toRecord(nodeData.serviceTable);
5462
+ const serviceTable = toRecord(nodeData$1.serviceTable);
5478
5463
  const serviceName = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.serviceName);
5479
5464
  const databaseName = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.databaseName);
5480
5465
  const tableName = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.tableName);
@@ -5536,17 +5521,17 @@ function buildContextNodes(graphNodes, nodeIdMap) {
5536
5521
  if (Object.keys(dynamicData).length > 0) nodeContext.data = dynamicData;
5537
5522
  const position = pickPosition(node.position);
5538
5523
  if (position) nodeContext.___position = position;
5539
- const internalData = Object.entries(nodeData).reduce((acc, [key, value]) => {
5524
+ const internalData = Object.entries(nodeData$1).reduce((acc, [key, value]) => {
5540
5525
  if (KNOWN_NODE_DATA_KEYS.has(key)) return acc;
5541
5526
  acc[key] = value;
5542
5527
  return acc;
5543
5528
  }, {});
5544
- if (nodeType === "builder" && Array.isArray(nodeData.componentFields)) internalData.componentFields = nodeData.componentFields;
5545
- const iconSrc = pickString(nodeData.iconSrc);
5529
+ if (nodeType === "builder" && Array.isArray(nodeData$1.componentFields)) internalData.componentFields = nodeData$1.componentFields;
5530
+ const iconSrc = pickString(nodeData$1.iconSrc);
5546
5531
  if (iconSrc) internalData.iconSrc = iconSrc;
5547
- const label = pickString(nodeData.label);
5532
+ const label = pickString(nodeData$1.label);
5548
5533
  if (label) internalData.label = label;
5549
- const internalCloud = pickString(nodeData.cloud);
5534
+ const internalCloud = pickString(nodeData$1.cloud);
5550
5535
  if (internalCloud) internalData.cloud = internalCloud;
5551
5536
  if (Object.keys(internalData).length > 0) nodeContext.___internal = internalData;
5552
5537
  if (Object.keys(nodeContext).length > 0) contextNodes[mappedNodeId] = nodeContext;
@@ -5563,6 +5548,205 @@ function buildValidatedContext(graphNodes, edges, groupNodes, nodeIdMap) {
5563
5548
  if (Object.keys(contextGroups).length > 0) context.groups = contextGroups;
5564
5549
  return require_headless.contextSchema.parse(context);
5565
5550
  }
5551
+ function nodeData(node) {
5552
+ var _node$data;
5553
+ return (_node$data = node.data) !== null && _node$data !== void 0 ? _node$data : {};
5554
+ }
5555
+ function edgeData(edge) {
5556
+ var _edge$data;
5557
+ return (_edge$data = edge.data) !== null && _edge$data !== void 0 ? _edge$data : {};
5558
+ }
5559
+ function isC4ReactFlowDiagram(nodes) {
5560
+ return nodes.some((node) => node.type === "c4" || node.type === "c4Boundary");
5561
+ }
5562
+ function isC4Element(node) {
5563
+ if (node.type !== "c4" && node.type !== "subDiagram") return false;
5564
+ const kind = nodeData(node).c4Kind;
5565
+ return kind === "person" || kind === "system" || kind === "container" || kind === "component";
5566
+ }
5567
+ function isC4Boundary(node) {
5568
+ return node.type === "c4Boundary";
5569
+ }
5570
+ function quoteC4Value(value) {
5571
+ return `"${value.replace(/"/g, "\\\"").replace(/\r\n?/g, "\n").replace(/\n/g, "<br/>").trim()}"`;
5572
+ }
5573
+ function nodeName(node) {
5574
+ var _node$data2;
5575
+ const fields = (_node$data2 = node.data) === null || _node$data2 === void 0 ? void 0 : _node$data2.componentFields;
5576
+ if (Array.isArray(fields)) {
5577
+ var _field$data;
5578
+ const field = fields.find((candidate) => (candidate === null || candidate === void 0 ? void 0 : candidate.componentFieldId) === "name");
5579
+ const value = field === null || field === void 0 || (_field$data = field.data) === null || _field$data === void 0 || (_field$data = _field$data[0]) === null || _field$data === void 0 ? void 0 : _field$data.value;
5580
+ if (typeof value === "string" && value.trim()) return value;
5581
+ }
5582
+ const diagramName = nodeData(node).diagramName;
5583
+ if (typeof diagramName === "string" && diagramName) return diagramName;
5584
+ return node.id;
5585
+ }
5586
+ function c4ElementKeyword(kind, shape, isExternal) {
5587
+ let keyword;
5588
+ if (kind === "person") keyword = "Person";
5589
+ else if (kind === "system") keyword = "System";
5590
+ else if (kind === "container") keyword = "Container";
5591
+ else if (kind === "component") keyword = "Component";
5592
+ else throw new Error(`Unsupported C4 element kind: ${String(kind)}`);
5593
+ if (shape === "db") keyword += "Db";
5594
+ if (shape === "queue") keyword += "Queue";
5595
+ if (isExternal) keyword += "_Ext";
5596
+ return keyword;
5597
+ }
5598
+ function c4BoundaryKeyword(kind, nodeType) {
5599
+ if (kind === "enterprise") return "Enterprise_Boundary";
5600
+ if (kind === "system") return "System_Boundary";
5601
+ if (kind === "container") return "Container_Boundary";
5602
+ if (kind === "node") {
5603
+ if (nodeType === "nodeL") return "Node_L";
5604
+ if (nodeType === "nodeR") return "Node_R";
5605
+ return "Deployment_Node";
5606
+ }
5607
+ return "Boundary";
5608
+ }
5609
+ function c4RelationshipKeyword(direction) {
5610
+ if (direction === "default") return "Rel";
5611
+ if (direction === "bi") return "BiRel";
5612
+ if (direction === "back") return "Rel_Back";
5613
+ if (direction === "up") return "Rel_U";
5614
+ if (direction === "down") return "Rel_D";
5615
+ if (direction === "left") return "Rel_L";
5616
+ if (direction === "right") return "Rel_R";
5617
+ throw new Error(`Unsupported C4 relationship direction: ${String(direction)}`);
5618
+ }
5619
+ function resolveRelDirection(edge) {
5620
+ const stored = edgeData(edge).c4RelDirection;
5621
+ if (stored) return stored;
5622
+ if (edge.markerStart) return "bi";
5623
+ if (edge.sourceHandle === "source-top") return "up";
5624
+ if (edge.sourceHandle === "source-bottom") return "down";
5625
+ if (edge.sourceHandle === "source-left") return "left";
5626
+ if (edge.sourceHandle === "source-right") return "right";
5627
+ return "default";
5628
+ }
5629
+ function relationshipLabel(edge, technology) {
5630
+ const label = typeof edge.label === "string" ? edge.label : "";
5631
+ if (!technology) return label;
5632
+ const suffix = ` [${technology}]`;
5633
+ if (label.endsWith(suffix)) return label.slice(0, -suffix.length);
5634
+ return label;
5635
+ }
5636
+ function resolveDiagramType(c4Nodes) {
5637
+ for (const node of c4Nodes) {
5638
+ const stored = nodeData(node).c4DiagramType;
5639
+ if (stored) return stored;
5640
+ }
5641
+ if (c4Nodes.some((node) => nodeData(node).c4Kind === "component")) return "C4Component";
5642
+ if (c4Nodes.some((node) => nodeData(node).c4Kind === "container")) return "C4Container";
5643
+ return "C4Context";
5644
+ }
5645
+ function trimTrailingSlots(values, keep) {
5646
+ const trimmed = [...values];
5647
+ while (trimmed.length > keep && trimmed[trimmed.length - 1] === "") trimmed.pop();
5648
+ return trimmed;
5649
+ }
5650
+ function emitC4Mermaid(nodes, edges) {
5651
+ const c4Nodes = nodes.filter((node) => isC4Element(node) || isC4Boundary(node));
5652
+ const c4NodeIds = new Set(c4Nodes.map((node) => node.id));
5653
+ const boundaryIds = new Set(c4Nodes.filter((node) => isC4Boundary(node)).map((node) => node.id));
5654
+ function parentOf(node) {
5655
+ if (node.parentId && boundaryIds.has(node.parentId)) return node.parentId;
5656
+ }
5657
+ function renderNode(node, indentation) {
5658
+ const data = nodeData(node);
5659
+ const name = quoteC4Value(nodeName(node));
5660
+ if (isC4Element(node)) {
5661
+ const values$1 = [node.id, name];
5662
+ if (data.c4Kind === "container" || data.c4Kind === "component") values$1.push(data.technology ? quoteC4Value(data.technology) : "");
5663
+ values$1.push(data.description ? quoteC4Value(data.description) : "");
5664
+ const trimmed$1 = trimTrailingSlots(values$1, 2);
5665
+ const link = data.diagramId ? `uig:${data.diagramId}` : data.link;
5666
+ if (link) trimmed$1.push(`$link=${quoteC4Value(link)}`);
5667
+ return `${indentation}${c4ElementKeyword(data.c4Kind, data.c4Shape, data.isExternal === true)}(${trimmed$1.join(", ")})`;
5668
+ }
5669
+ const keyword = c4BoundaryKeyword(data.c4BoundaryKind, data.c4NodeType);
5670
+ const values = [node.id, name];
5671
+ if (keyword === "Boundary" && data.boundaryType) values.push(quoteC4Value(data.boundaryType));
5672
+ if (data.c4BoundaryKind === "node") {
5673
+ values.push(data.boundaryType ? quoteC4Value(data.boundaryType) : "\"node\"");
5674
+ values.push(data.description ? quoteC4Value(data.description) : "");
5675
+ }
5676
+ const trimmed = trimTrailingSlots(values, 2);
5677
+ if (data.link) trimmed.push(`$link=${quoteC4Value(data.link)}`);
5678
+ return `${indentation}${keyword}(${trimmed.join(", ")}) {`;
5679
+ }
5680
+ function renderChildren(parentId, indentation) {
5681
+ const lines = [];
5682
+ for (const node of c4Nodes) {
5683
+ if (parentOf(node) !== parentId) continue;
5684
+ lines.push(renderNode(node, indentation));
5685
+ if (isC4Boundary(node)) {
5686
+ lines.push(...renderChildren(node.id, `${indentation} `));
5687
+ lines.push(`${indentation}}`);
5688
+ }
5689
+ }
5690
+ return lines;
5691
+ }
5692
+ const relationships = edges.flatMap((edge) => {
5693
+ if (!c4NodeIds.has(edge.source) || !c4NodeIds.has(edge.target)) return [];
5694
+ const data = edgeData(edge);
5695
+ const direction = resolveRelDirection(edge);
5696
+ const isBack = direction === "back";
5697
+ const values = [
5698
+ isBack ? edge.target : edge.source,
5699
+ isBack ? edge.source : edge.target,
5700
+ quoteC4Value(relationshipLabel(edge, data.c4RelTechnology)),
5701
+ data.c4RelTechnology ? quoteC4Value(data.c4RelTechnology) : "",
5702
+ data.c4RelDescription ? quoteC4Value(data.c4RelDescription) : ""
5703
+ ];
5704
+ return `${c4RelationshipKeyword(direction)}(${trimTrailingSlots(values, 3).join(", ")})`;
5705
+ });
5706
+ return {
5707
+ mermaid: [
5708
+ resolveDiagramType(c4Nodes),
5709
+ ...renderChildren(void 0, ""),
5710
+ ...relationships
5711
+ ].join("\n"),
5712
+ nodeIdMap: new Map(c4Nodes.map((node) => [node.id, node.id]))
5713
+ };
5714
+ }
5715
+ function convertReactFlowToC4Mermaid(nodes, edges) {
5716
+ return emitC4Mermaid(nodes, edges).mermaid;
5717
+ }
5718
+ function convertReactFlowToC4UiGraph(nodes, edges) {
5719
+ const { mermaid: mermaid$2, nodeIdMap } = emitC4Mermaid(nodes, edges);
5720
+ return {
5721
+ mermaid: mermaid$2,
5722
+ context: buildValidatedContext(nodes, edges, [], nodeIdMap)
5723
+ };
5724
+ }
5725
+ function sanitizeMermaidLabels(src) {
5726
+ if (!src) return src;
5727
+ const subgraphFixed = src.replace(/([A-Za-z0-9_]+)\[((?:(?![\"']).)*?)\]/g, (m, id, label) => {
5728
+ if (/^[\"']/.test(label)) return m;
5729
+ if (/[()\"\[\],:;]/.test(label)) return `${id}[\"${String(label).replace(/\\/g, "\\\\").replace(/\"/g, "\\\"")}\"]`;
5730
+ return m;
5731
+ }).replace(/^([ \t]*subgraph\s+)([^\n\r]+)(\|[^\n\r]*)?$/gim, (m, pre, title, rest) => {
5732
+ const t = String(title).trim();
5733
+ if (/^[\"']/.test(t)) return m;
5734
+ if (/[()\"\[\],:;]/.test(t)) return `${pre}\"${t.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"")}\"${rest || ""}`;
5735
+ return m;
5736
+ });
5737
+ const diagRegex = /\b(graph|flowchart|sequenceDiagram|stateDiagram|classDiagram|gantt|journey|erDiagram|gitGraph|pie|timeline|infoDiagram)\b/i;
5738
+ const allStarts = [];
5739
+ let mm;
5740
+ const globalRegex = new RegExp(diagRegex.source, "gim");
5741
+ while ((mm = globalRegex.exec(subgraphFixed)) !== null) {
5742
+ allStarts.push(mm.index);
5743
+ if (globalRegex.lastIndex === mm.index) globalRegex.lastIndex++;
5744
+ }
5745
+ if (allStarts.length <= 1) return subgraphFixed;
5746
+ const first = allStarts[0];
5747
+ const second = allStarts[1];
5748
+ return subgraphFixed.slice(first, second).trim();
5749
+ }
5566
5750
  function isSequenceDiagram(nodes) {
5567
5751
  return nodes.some((node) => node.type === "sequenceParticipant");
5568
5752
  }
@@ -6097,7 +6281,7 @@ function normalizeContextMarker(marker) {
6097
6281
  };
6098
6282
  return { type };
6099
6283
  }
6100
- function convertMermaidToReactFlowWithContext(_x3, _x4, _x5) {
6284
+ function convertMermaidToReactFlowWithContext(_x4, _x5, _x6) {
6101
6285
  return _convertMermaidToReactFlowWithContext.apply(this, arguments);
6102
6286
  }
6103
6287
  function _convertMermaidToReactFlowWithContext() {
@@ -6232,10 +6416,26 @@ function _convertMermaidToReactFlowWithContext() {
6232
6416
  const childNodes = (0, daily_code.arrayNonNullable)(((_groupCtx$nodes = groupCtx.nodes) !== null && _groupCtx$nodes !== void 0 ? _groupCtx$nodes : []).map((nodeId$1) => resolvedNodes.find((n) => n.id === nodeId$1)));
6233
6417
  return generateGroupNodeFromNodes(nodeId, (_groupCtx$name = groupCtx.name) !== null && _groupCtx$name !== void 0 ? _groupCtx$name : "Group", childNodes);
6234
6418
  });
6419
+ const edgeOrdinals = /* @__PURE__ */ new Map();
6420
+ const edgeContextKeys = reactFlowData.edges.map((edge) => {
6421
+ var _edgeOrdinals$get;
6422
+ const pair = `${edge.source}-${edge.target}`;
6423
+ const ordinal = (_edgeOrdinals$get = edgeOrdinals.get(pair)) !== null && _edgeOrdinals$get !== void 0 ? _edgeOrdinals$get : 0;
6424
+ edgeOrdinals.set(pair, ordinal + 1);
6425
+ if (ordinal === 0) return {
6426
+ pair,
6427
+ key: pair
6428
+ };
6429
+ return {
6430
+ pair,
6431
+ key: `${pair}#${ordinal}`
6432
+ };
6433
+ });
6235
6434
  const rfEdgesPromises = reactFlowData.edges.map(function() {
6236
- var _ref2 = _asyncToGenerator(function* (edge) {
6237
- var _validatedContext$edg, _ctx$type, _ctx$sourceHandle, _ctx$targetHandle, _normalizeContextMark, _normalizeContextMark2, _ctx$label, _ctx$style$borderAnim, _ctx$style5, _ctx$style$stroke, _ctx$style6, _edge$style, _ctx$style$strokeWidt, _ctx$style7, _edge$style2, _ctx$style8, _ctx$style9, _ctx$style10, _edge$style3;
6238
- const ctx = (_validatedContext$edg = validatedContext.edges) === null || _validatedContext$edg === void 0 ? void 0 : _validatedContext$edg[`${edge.source}-${edge.target}`];
6435
+ var _ref3 = _asyncToGenerator(function* (edge, index) {
6436
+ var _ref2, _validatedContext$edg, _validatedContext$edg2, _validatedContext$edg3, _ctx$type, _ctx$sourceHandle, _ctx$targetHandle, _normalizeContextMark, _normalizeContextMark2, _ctx$label, _ctx$style$borderAnim, _ctx$style5, _ctx$style$stroke, _ctx$style6, _edge$style, _ctx$style$strokeWidt, _ctx$style7, _edge$style2, _ctx$style8, _ctx$style9, _ctx$style10, _edge$style3;
6437
+ const { pair, key } = edgeContextKeys[index];
6438
+ const ctx = (_ref2 = (_validatedContext$edg = (_validatedContext$edg2 = validatedContext.edges) === null || _validatedContext$edg2 === void 0 ? void 0 : _validatedContext$edg2[key]) !== null && _validatedContext$edg !== void 0 ? _validatedContext$edg : (_validatedContext$edg3 = validatedContext.edges) === null || _validatedContext$edg3 === void 0 ? void 0 : _validatedContext$edg3[pair]) !== null && _ref2 !== void 0 ? _ref2 : null;
6239
6439
  if (!ctx) return edge;
6240
6440
  return _objectSpread2(_objectSpread2({}, edge), {}, {
6241
6441
  type: (_ctx$type = ctx.type) !== null && _ctx$type !== void 0 ? _ctx$type : edge.type,
@@ -6253,8 +6453,8 @@ function _convertMermaidToReactFlowWithContext() {
6253
6453
  })
6254
6454
  });
6255
6455
  });
6256
- return function(_x2) {
6257
- return _ref2.apply(this, arguments);
6456
+ return function(_x2, _x3) {
6457
+ return _ref3.apply(this, arguments);
6258
6458
  };
6259
6459
  }());
6260
6460
  const resolvedEdges = yield Promise.all(rfEdgesPromises);
@@ -6270,6 +6470,10 @@ function _convertMermaidToReactFlowWithContext() {
6270
6470
  edges: resolvedEdges,
6271
6471
  nodes: combinedNodes
6272
6472
  };
6473
+ if (isC4ReactFlowDiagram(combinedNodes)) return {
6474
+ edges: resolvedEdges,
6475
+ nodes: combinedNodes
6476
+ };
6273
6477
  return {
6274
6478
  edges: resolvedEdges,
6275
6479
  nodes: (options === null || options === void 0 ? void 0 : options.repositionNodes) ? resizeNodesLayouts(combinedNodes) : combinedNodes
@@ -6330,8 +6534,8 @@ function buildNodeIdMap(graphNodes) {
6330
6534
  }
6331
6535
  function resolveMermaidNodeLabel(node) {
6332
6536
  const nodeType = node.type;
6333
- const nodeData = toRecord(node.data);
6334
- const componentFields = Array.isArray(nodeData === null || nodeData === void 0 ? void 0 : nodeData.componentFields) ? nodeData.componentFields.map((field) => toRecord(field)).filter((field) => field !== void 0) : [];
6537
+ const nodeData$1 = toRecord(node.data);
6538
+ const componentFields = Array.isArray(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.componentFields) ? nodeData$1.componentFields.map((field) => toRecord(field)).filter((field) => field !== void 0) : [];
6335
6539
  const name = getFieldString(componentFields, "Name");
6336
6540
  if (nodeType === "text") return getFieldString(componentFields, "Text");
6337
6541
  if (nodeType === "code") return getFieldString(componentFields, "Code");
@@ -6427,9 +6631,9 @@ function formatDetailValue(value) {
6427
6631
  return entries.join(",");
6428
6632
  }
6429
6633
  }
6430
- function getNodeName(nodeData, componentFields) {
6634
+ function getNodeName(nodeData$1, componentFields) {
6431
6635
  var _getFieldString;
6432
- return (_getFieldString = getFieldString(componentFields, "Name")) !== null && _getFieldString !== void 0 ? _getFieldString : pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.name);
6636
+ return (_getFieldString = getFieldString(componentFields, "Name")) !== null && _getFieldString !== void 0 ? _getFieldString : pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.name);
6433
6637
  }
6434
6638
  function buildFieldLines(componentFields, excludedLabels) {
6435
6639
  const lines = [];
@@ -6461,25 +6665,25 @@ function buildDetailedLabel(lines) {
6461
6665
  }
6462
6666
  function resolveMermaidDetailedNodeLabel(node) {
6463
6667
  const nodeType = pickString(node.type);
6464
- const nodeData = toRecord(node.data);
6465
- const componentFields = toComponentFields(nodeData === null || nodeData === void 0 ? void 0 : nodeData.componentFields);
6466
- const name = getNodeName(nodeData, componentFields);
6668
+ const nodeData$1 = toRecord(node.data);
6669
+ const componentFields = toComponentFields(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.componentFields);
6670
+ const name = getNodeName(nodeData$1, componentFields);
6467
6671
  if (nodeType === "text") {
6468
6672
  var _getFieldString2;
6469
- const text = (_getFieldString2 = getFieldString(componentFields, "Text")) !== null && _getFieldString2 !== void 0 ? _getFieldString2 : pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.value);
6673
+ const text = (_getFieldString2 = getFieldString(componentFields, "Text")) !== null && _getFieldString2 !== void 0 ? _getFieldString2 : pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.value);
6470
6674
  return buildDetailedLabel([text ? `Text: ${text}` : "Text", ...buildFieldLines(componentFields, new Set(["name", "text"]))]);
6471
6675
  }
6472
6676
  if (nodeType === "code") {
6473
6677
  var _getFieldString3, _code$split$;
6474
- const code = (_getFieldString3 = getFieldString(componentFields, "Code")) !== null && _getFieldString3 !== void 0 ? _getFieldString3 : pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.value);
6678
+ const code = (_getFieldString3 = getFieldString(componentFields, "Code")) !== null && _getFieldString3 !== void 0 ? _getFieldString3 : pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.value);
6475
6679
  const firstLine = code === null || code === void 0 || (_code$split$ = code.split(/\r?\n/)[0]) === null || _code$split$ === void 0 ? void 0 : _code$split$.trim();
6476
6680
  return buildDetailedLabel([firstLine ? `Code: ${firstLine}` : "Code", ...buildFieldLines(componentFields, new Set(["name", "code"]))]);
6477
6681
  }
6478
6682
  if (nodeType === "data-source" || nodeType === "databaseTableSQL") {
6479
6683
  var _pickString, _pickString2, _pickString3;
6480
6684
  const lines = [];
6481
- const serviceTable = toRecord(nodeData === null || nodeData === void 0 ? void 0 : nodeData.serviceTable);
6482
- const dbConfig = toRecord(nodeData === null || nodeData === void 0 ? void 0 : nodeData.dbConfig);
6685
+ const serviceTable = toRecord(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.serviceTable);
6686
+ const dbConfig = toRecord(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.dbConfig);
6483
6687
  const database = (_pickString = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.databaseName)) !== null && _pickString !== void 0 ? _pickString : pickString(dbConfig === null || dbConfig === void 0 ? void 0 : dbConfig.databaseName);
6484
6688
  const tableName = (_pickString2 = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.tableName)) !== null && _pickString2 !== void 0 ? _pickString2 : pickString(dbConfig === null || dbConfig === void 0 ? void 0 : dbConfig.tableName);
6485
6689
  const dbService = (_pickString3 = pickString(serviceTable === null || serviceTable === void 0 ? void 0 : serviceTable.serviceName)) !== null && _pickString3 !== void 0 ? _pickString3 : pickString(dbConfig === null || dbConfig === void 0 ? void 0 : dbConfig.serviceName);
@@ -6493,9 +6697,9 @@ function resolveMermaidDetailedNodeLabel(node) {
6493
6697
  if (nodeType === "cloud") {
6494
6698
  const lines = [];
6495
6699
  lines.push(name ? `Cloud: ${name}` : "Cloud");
6496
- const cloud = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.cloud);
6700
+ const cloud = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.cloud);
6497
6701
  if (cloud) lines.push(`provider: ${cloud}`);
6498
- const service = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.service);
6702
+ const service = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.service);
6499
6703
  if (service) lines.push(`service: ${service}`);
6500
6704
  lines.push(...buildFieldLines(componentFields, new Set(["name"])));
6501
6705
  return buildDetailedLabel(lines);
@@ -6503,11 +6707,11 @@ function resolveMermaidDetailedNodeLabel(node) {
6503
6707
  if (nodeType === "table" || nodeType === "dataTableInterface") {
6504
6708
  var _pickString4;
6505
6709
  const lines = [];
6506
- const table = toRecord(nodeData === null || nodeData === void 0 ? void 0 : nodeData.table);
6710
+ const table = toRecord(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.table);
6507
6711
  const tableName = (_pickString4 = pickString(table === null || table === void 0 ? void 0 : table.name)) !== null && _pickString4 !== void 0 ? _pickString4 : name;
6508
6712
  lines.push(tableName ? `Table: ${tableName}` : "Table");
6509
- const columns = Array.isArray(nodeData === null || nodeData === void 0 ? void 0 : nodeData.columns) ? nodeData.columns.filter((value) => typeof value === "string").length : Array.isArray(table === null || table === void 0 ? void 0 : table.columns) ? table.columns.length : 0;
6510
- const rows = Array.isArray(nodeData === null || nodeData === void 0 ? void 0 : nodeData.rows) ? nodeData.rows.filter((value) => Array.isArray(value)).length : Array.isArray(table === null || table === void 0 ? void 0 : table.rows) ? table.rows.length : 0;
6713
+ const columns = Array.isArray(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.columns) ? nodeData$1.columns.filter((value) => typeof value === "string").length : Array.isArray(table === null || table === void 0 ? void 0 : table.columns) ? table.columns.length : 0;
6714
+ const rows = Array.isArray(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.rows) ? nodeData$1.rows.filter((value) => Array.isArray(value)).length : Array.isArray(table === null || table === void 0 ? void 0 : table.rows) ? table.rows.length : 0;
6511
6715
  lines.push(`columns: ${columns}`);
6512
6716
  lines.push(`rows: ${rows}`);
6513
6717
  lines.push(...buildFieldLines(componentFields, new Set(["name"])));
@@ -6520,7 +6724,7 @@ function resolveMermaidDetailedNodeLabel(node) {
6520
6724
  return;
6521
6725
  }
6522
6726
  if (nodeType === "gif") {
6523
- const src = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.src);
6727
+ const src = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.src);
6524
6728
  return buildDetailedLabel([
6525
6729
  name ? `Gif: ${name}` : src ? `Gif: ${src}` : "Gif",
6526
6730
  ...src ? [`src: ${src}`] : [],
@@ -6528,7 +6732,7 @@ function resolveMermaidDetailedNodeLabel(node) {
6528
6732
  ]);
6529
6733
  }
6530
6734
  if (nodeType === "image") {
6531
- const src = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.src);
6735
+ const src = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.src);
6532
6736
  return buildDetailedLabel([
6533
6737
  name ? `Image: ${name}` : src ? `Image: ${src}` : "Image",
6534
6738
  ...src ? [`src: ${src}`] : [],
@@ -6536,7 +6740,7 @@ function resolveMermaidDetailedNodeLabel(node) {
6536
6740
  ]);
6537
6741
  }
6538
6742
  if (nodeType === "group") {
6539
- const childCount = Array.isArray(nodeData === null || nodeData === void 0 ? void 0 : nodeData.childNodes) ? nodeData.childNodes.length : 0;
6743
+ const childCount = Array.isArray(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.childNodes) ? nodeData$1.childNodes.length : 0;
6540
6744
  return buildDetailedLabel([
6541
6745
  name ? `Group: ${name}` : "Group",
6542
6746
  `children: ${childCount}`,
@@ -6545,10 +6749,10 @@ function resolveMermaidDetailedNodeLabel(node) {
6545
6749
  }
6546
6750
  if (nodeType === "sequenceParticipant") {
6547
6751
  var _getFieldString4;
6548
- const label = (_getFieldString4 = getFieldString(componentFields, "Label")) !== null && _getFieldString4 !== void 0 ? _getFieldString4 : pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.label);
6752
+ const label = (_getFieldString4 = getFieldString(componentFields, "Label")) !== null && _getFieldString4 !== void 0 ? _getFieldString4 : pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.label);
6549
6753
  const participantName = name !== null && name !== void 0 ? name : label;
6550
- const rowCount = typeof (nodeData === null || nodeData === void 0 ? void 0 : nodeData.rowCount) === "number" ? nodeData.rowCount : void 0;
6551
- const color = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.color);
6754
+ const rowCount = typeof (nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.rowCount) === "number" ? nodeData$1.rowCount : void 0;
6755
+ const color = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.color);
6552
6756
  return buildDetailedLabel([
6553
6757
  participantName ? `SequenceParticipant: ${participantName}` : "SequenceParticipant",
6554
6758
  ...typeof rowCount === "number" ? [`rows: ${rowCount}`] : [],
@@ -6556,9 +6760,9 @@ function resolveMermaidDetailedNodeLabel(node) {
6556
6760
  ...buildFieldLines(componentFields, new Set(["name", "label"]))
6557
6761
  ]);
6558
6762
  }
6559
- if (nodeType === "comment") return buildDetailedLabel([`Comment: ${(typeof (nodeData === null || nodeData === void 0 ? void 0 : nodeData.isResolved) === "boolean" ? nodeData.isResolved : void 0) ? "Resolved" : "Open"}`, ...buildFieldLines(componentFields, new Set(["name"]))]);
6763
+ if (nodeType === "comment") return buildDetailedLabel([`Comment: ${(typeof (nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.isResolved) === "boolean" ? nodeData$1.isResolved : void 0) ? "Resolved" : "Open"}`, ...buildFieldLines(componentFields, new Set(["name"]))]);
6560
6764
  if (nodeType === "builder") {
6561
- const componentId = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.componentId);
6765
+ const componentId = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.componentId);
6562
6766
  return buildDetailedLabel([
6563
6767
  name ? `Builder: ${name}` : "Builder",
6564
6768
  ...componentId ? [`componentId: ${componentId}`] : [],
@@ -6575,7 +6779,7 @@ function resolveMermaidDetailedNodeLabel(node) {
6575
6779
  ])));
6576
6780
  return buildDetailedLabel(lines);
6577
6781
  }
6578
- const fallbackLabel = pickString(nodeData === null || nodeData === void 0 ? void 0 : nodeData.label);
6782
+ const fallbackLabel = pickString(nodeData$1 === null || nodeData$1 === void 0 ? void 0 : nodeData$1.label);
6579
6783
  if (fallbackLabel) return `${nodeType ? nodeType.charAt(0).toUpperCase() + nodeType.slice(1) : "Node"}: ${fallbackLabel}`;
6580
6784
  }
6581
6785
  function escapeMermaidEdgeLabelText(value) {
@@ -6666,6 +6870,8 @@ exports.convertMermaidToReactFlow = convertMermaidToReactFlow;
6666
6870
  exports.convertMermaidToReactFlowWithContext = convertMermaidToReactFlowWithContext;
6667
6871
  exports.convertMongoSchemaToAst = convertMongoSchemaToAst;
6668
6872
  exports.convertNoSQLToAst = convertNoSQLToAst;
6873
+ exports.convertReactFlowToC4Mermaid = convertReactFlowToC4Mermaid;
6874
+ exports.convertReactFlowToC4UiGraph = convertReactFlowToC4UiGraph;
6669
6875
  exports.convertReactFlowToSequenceMermaid = convertReactFlowToSequenceMermaid;
6670
6876
  exports.convertReactFlowToSequenceUiGraph = convertReactFlowToSequenceUiGraph;
6671
6877
  exports.convertUiGraphToMermaid = convertUiGraphToMermaid;
@@ -6675,6 +6881,7 @@ exports.generateTableNodeId = generateTableNodeId;
6675
6881
  exports.generateUUID = generateUUID;
6676
6882
  exports.getC4ElementColors = getC4ElementColors;
6677
6883
  exports.isC4Diagram = isC4Diagram;
6884
+ exports.isC4ReactFlowDiagram = isC4ReactFlowDiagram;
6678
6885
  exports.isSequenceDiagram = isSequenceDiagram;
6679
6886
  exports.parseC4Diagram = parseC4Diagram;
6680
6887
  exports.sanitizeMermaidLabels = sanitizeMermaidLabels;