@likec4/generators 1.55.0 → 1.56.0

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.
@@ -1,3 +1,4 @@
1
+ //#region \0rolldown/runtime.js
1
2
  var __defProp = Object.defineProperty;
2
3
  var __exportAll = (all, no_symbols) => {
3
4
  let target = {};
@@ -8,4 +9,5 @@ var __exportAll = (all, no_symbols) => {
8
9
  if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
9
10
  return target;
10
11
  };
12
+ //#endregion
11
13
  export { __exportAll as t };
package/dist/index.mjs CHANGED
@@ -5,6 +5,7 @@ import { RichText, flattenMarkdownOrString } from "@likec4/core/types";
5
5
  import pako from "pako";
6
6
  import JSON5 from "json5";
7
7
  import { compareNatural, invariant as invariant$1, sortNaturalByFqn } from "@likec4/core/utils";
8
+ //#region src/d2/generate-d2.ts
8
9
  const capitalizeFirstLetter$2 = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
9
10
  const fqnName$2 = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter$2).join("");
10
11
  const nodeName$2 = (node) => {
@@ -52,6 +53,8 @@ function generateD2(viewmodel) {
52
53
  };
53
54
  return toString(new CompositeGeneratorNode().append("direction: ", d2direction(view), NL, NL).append(joinToNode(nodes.filter((n) => isNullish(n.parent)), (n) => printNode(n), { appendNewLineIfNotEmpty: true })).appendIf(edges.length > 0, NL, joinToNode(edges, (e) => printEdge(e), { appendNewLineIfNotEmpty: true })));
54
55
  }
56
+ //#endregion
57
+ //#region src/drawio/constants.ts
55
58
  /**
56
59
  * DrawIO protocol and layout constants. Single source of truth so export/parse
57
60
  * stay in sync and magic numbers are named for readability.
@@ -60,47 +63,19 @@ function generateD2(viewmodel) {
60
63
  const DRAWIO_PAGE_LINK_PREFIX = "data:page/id,likec4-";
61
64
  /** Diagram (tab) id inside mxfile; we use "likec4-<viewId>" so Draw.io opens the correct tab. */
62
65
  const DRAWIO_DIAGRAM_ID_PREFIX = "likec4-";
63
- /** Fixed canvas size so the diagram opens centered in Draw.io (layout bounds often equal content). */
64
- const DEFAULT_CANVAS_WIDTH = 800;
65
- const DEFAULT_CANVAS_HEIGHT = 600;
66
- /** Default node bbox when layout has no position (used to detect "unlaid" nodes for spread/wrap). */
67
- const DEFAULT_NODE_WIDTH = 120;
68
- const DEFAULT_NODE_HEIGHT = 60;
69
- /** Vertical gap when spreading multiple nodes that share the same default bbox. */
70
- const NODES_SPREAD_GAP = 24;
71
66
  /** First id assigned to container title cells (incremented per container). */
72
67
  const CONTAINER_TITLE_CELL_ID_START = 1e4;
73
- /** Container title text cell: min/max width (px), approximate width per character, height, inset from container edge. */
74
- const CONTAINER_TITLE_MIN_WIDTH_PX = 60;
75
- const CONTAINER_TITLE_MAX_WIDTH_PX = 260;
76
- const CONTAINER_TITLE_CHAR_WIDTH_PX = 8;
77
- const CONTAINER_TITLE_HEIGHT_PX = 18;
78
- const CONTAINER_TITLE_INSET_X = 8;
79
- const CONTAINER_TITLE_INSET_Y = 8;
80
- /** Max height (px) for container title area when matching title cell to container (parse). */
81
- const CONTAINER_TITLE_AREA_MAX_HEIGHT_PX = 40;
82
68
  /** Ratio of container height used for title area when matching (parse). */
83
69
  const CONTAINER_TITLE_AREA_HEIGHT_RATIO = .5;
84
- /** Tolerance (px) for title cell position inside container bounds (parse). */
85
- const CONTAINER_TITLE_AREA_TOLERANCE = 2;
86
- /** Default container fill opacity (0–100) when not set in style. */
87
- const DEFAULT_CONTAINER_OPACITY = 15;
88
- /** Default node fill/stroke/font when no theme color (hex). */
89
- const DEFAULT_NODE_FILL_HEX = "#dae8fc";
90
- const DEFAULT_NODE_STROKE_HEX = "#2563eb";
91
- const DEFAULT_NODE_FONT_HEX = "#1e40af";
92
- /** mxGraphModel page dimensions (draw.io default A4-like). */
93
- const MXGRAPH_PAGE_WIDTH = 827;
94
70
  const MXGRAPH_PAGE_HEIGHT = 1169;
95
- /** mxGraphModel default grid origin (dx, dy) in mxGraphModel attribute. */
96
- const MXGRAPH_DEFAULT_DX = 800;
97
- const MXGRAPH_DEFAULT_DY = 800;
98
71
  /** Default filename when exporting all views into one .drawio file (CLI and playground). */
99
72
  const DEFAULT_DRAWIO_ALL_FILENAME = "diagrams.drawio";
100
73
  /** LikeC4 app font (matches --mantine-font-family / --likec4-app-font-default). Used in generate-drawio for cell text. */
101
74
  const LIKEC4_FONT_FAMILY = "'IBM Plex Sans Variable',ui-sans-serif,system-ui,sans-serif";
102
75
  /** Container title color in diagram (matches LikeC4 diagram compound title). Used in generate-drawio for container title cell. */
103
76
  const CONTAINER_TITLE_COLOR = "#74c0fc";
77
+ //#endregion
78
+ //#region src/drawio/xml-utils.ts
104
79
  /**
105
80
  * Shared XML escape/decode for DrawIO generate and parse.
106
81
  * Single place so escaping rules stay in sync (Clean Code 8.5.2).
@@ -121,6 +96,8 @@ function escapeXml(unsafe) {
121
96
  function decodeXmlEntities(s) {
122
97
  return s.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"").replaceAll("&apos;", "'").replaceAll("&amp;", "&");
123
98
  }
99
+ //#endregion
100
+ //#region src/drawio/parse-drawio.ts
124
101
  /**
125
102
  * Parse DrawIO (mxGraph) XML and generate LikeC4 source code.
126
103
  * Extracts vertices as elements and edges as relations; preserves colors, descriptions,
@@ -713,8 +690,8 @@ function computeContainerTitles(vertices) {
713
690
  const containerCells = vertices.filter((v) => v.style?.toLowerCase().includes("container=1") && v.x != null && v.y != null && v.width != null && v.height != null);
714
691
  for (const cont of containerCells) {
715
692
  const cw = cont.width, ch = cont.height;
716
- const titleAreaHeight = Math.min(CONTAINER_TITLE_AREA_MAX_HEIGHT_PX, ch * CONTAINER_TITLE_AREA_HEIGHT_RATIO) + CONTAINER_TITLE_AREA_TOLERANCE;
717
- const best = vertices.find((v) => v.id !== cont.id && v.parent === cont.id && (v.style?.toLowerCase().includes("shape=text") || v.style?.toLowerCase().includes("text;")) && v.x != null && v.y != null && v.x >= -CONTAINER_TITLE_AREA_TOLERANCE && v.x <= cw + CONTAINER_TITLE_AREA_TOLERANCE && v.y >= -CONTAINER_TITLE_AREA_TOLERANCE && v.y <= titleAreaHeight);
693
+ const titleAreaHeight = Math.min(40, ch * CONTAINER_TITLE_AREA_HEIGHT_RATIO) + 2;
694
+ const best = vertices.find((v) => v.id !== cont.id && v.parent === cont.id && (v.style?.toLowerCase().includes("shape=text") || v.style?.toLowerCase().includes("text;")) && v.x != null && v.y != null && v.x >= -2 && v.x <= cw + 2 && v.y >= -2 && v.y <= titleAreaHeight);
718
695
  if (best) {
719
696
  const raw = (best.value ?? "").trim();
720
697
  if (raw) {
@@ -1068,7 +1045,7 @@ function decompressDrawioDiagram(base64Content) {
1068
1045
  function getFirstDiagram(fullXml) {
1069
1046
  return getAllDiagrams(fullXml)[0] ?? {
1070
1047
  name: "index",
1071
- id: `${DRAWIO_DIAGRAM_ID_PREFIX}index`,
1048
+ id: `likec4-index`,
1072
1049
  content: ""
1073
1050
  };
1074
1051
  }
@@ -1092,7 +1069,7 @@ function getAllDiagrams(fullXml) {
1092
1069
  if (closeStart === -1) break;
1093
1070
  const inner = fullXml.slice(endOpen + 1, closeStart);
1094
1071
  const name = getAttr(attrs, "name") ?? (results.length === 0 ? "index" : `diagram_${results.length + 1}`);
1095
- const id = getAttr(attrs, "id") ?? `${DRAWIO_DIAGRAM_ID_PREFIX}${name}`;
1072
+ const id = getAttr(attrs, "id") ?? `likec4-${name}`;
1096
1073
  let content;
1097
1074
  if (inner.includes("<mxGraphModel")) content = inner;
1098
1075
  else if (inner.trim() === "") content = inner;
@@ -1506,6 +1483,8 @@ function parseDrawioRoundtripComments(c4Source) {
1506
1483
  };
1507
1484
  return null;
1508
1485
  }
1486
+ //#endregion
1487
+ //#region src/drawio/generate-drawio.ts
1509
1488
  /**
1510
1489
  * DrawIO diagram generator.
1511
1490
  *
@@ -1615,7 +1594,7 @@ function getDefaultStrokeWidth(borderVal, isContainer) {
1615
1594
  /** Apply stroke color override to base element colors (KISS: named function instead of IIFE). */
1616
1595
  function applyStrokeColorOverride(base, override) {
1617
1596
  return {
1618
- fill: base?.fill ?? DEFAULT_NODE_FILL_HEX,
1597
+ fill: base?.fill ?? "#dae8fc",
1619
1598
  stroke: override,
1620
1599
  font: base?.font ?? override
1621
1600
  };
@@ -1662,21 +1641,21 @@ function drawioShape(shape) {
1662
1641
  function getElementColors(viewmodel, color) {
1663
1642
  const elementColors = getThemeColorValues(viewmodel, color, "primary").elements;
1664
1643
  return {
1665
- fill: String(elementColors.fill ?? DEFAULT_NODE_FILL_HEX),
1666
- stroke: String(elementColors.stroke ?? DEFAULT_NODE_STROKE_HEX),
1667
- font: String(elementColors.hiContrast ?? elementColors.stroke ?? DEFAULT_NODE_FONT_HEX)
1644
+ fill: String(elementColors.fill ?? "#dae8fc"),
1645
+ stroke: String(elementColors.stroke ?? "#2563eb"),
1646
+ font: String(elementColors.hiContrast ?? elementColors.stroke ?? "#1e40af")
1668
1647
  };
1669
1648
  }
1670
1649
  /** Edge stroke (line) color from theme RelationshipColorValues.line. */
1671
1650
  function getEdgeStrokeColor(viewmodel, color) {
1672
1651
  const values = getThemeColorValues(viewmodel, color ?? "gray", "gray");
1673
- return String(values.relationships?.line ?? DEFAULT_NODE_FONT_HEX);
1652
+ return String(values.relationships?.line ?? "#1e40af");
1674
1653
  }
1675
1654
  /** Edge label font and background from theme (RelationshipColorValues.label, labelBg) for readable connector text. */
1676
1655
  function getEdgeLabelColors(viewmodel, color) {
1677
1656
  const rel = getThemeColorValues(viewmodel, color ?? "gray", "gray").relationships;
1678
1657
  return {
1679
- font: String(rel?.label ?? rel?.line ?? DEFAULT_NODE_FONT_HEX),
1658
+ font: String(rel?.label ?? rel?.line ?? "#1e40af"),
1680
1659
  background: String(rel?.labelBg ?? "#ffffff")
1681
1660
  };
1682
1661
  }
@@ -1895,9 +1874,9 @@ function computeNodeStylePartsAndValue(node, layout, options, viewmodel) {
1895
1874
  const strokeColorOverride = strokeColorByNodeId?.[node.id];
1896
1875
  const strokeWidthOverride = strokeWidthByNodeId?.[node.id];
1897
1876
  const elemColors = strokeColorOverride ? applyStrokeColorOverride(getElementColors(viewmodel, node.color), strokeColorOverride) : getElementColors(viewmodel, node.color);
1898
- const fillHex = elemColors?.fill ?? DEFAULT_NODE_FILL_HEX;
1899
- const strokeHex = elemColors?.stroke ?? DEFAULT_NODE_STROKE_HEX;
1900
- const fontHex = elemColors?.font ?? elemColors?.stroke ?? DEFAULT_NODE_FONT_HEX;
1877
+ const fillHex = elemColors?.fill ?? "#dae8fc";
1878
+ const strokeHex = elemColors?.stroke ?? "#2563eb";
1879
+ const fontHex = elemColors?.font ?? elemColors?.stroke ?? "#1e40af";
1901
1880
  const colorStyle = `fillColor=${fillHex};strokeColor=${strokeHex};fontColor=${fontHex};`;
1902
1881
  const nodeStyle = node.style;
1903
1882
  const fontSizePx = effectiveStyles.fontSize(nodeStyle?.textSize);
@@ -1906,7 +1885,7 @@ function computeNodeStylePartsAndValue(node, layout, options, viewmodel) {
1906
1885
  const strokeWidth = strokeWidthOverride ?? getDefaultStrokeWidth(borderVal, isContainer);
1907
1886
  const strokeWidthStyle = strokeWidth !== "" ? `strokeWidth=${strokeWidth};` : "";
1908
1887
  const containerDashed = getContainerDashedStyle(isContainer, borderVal);
1909
- const containerOpacityNum = isContainer === true ? nodeStyle?.opacity ?? DEFAULT_CONTAINER_OPACITY : void 0;
1888
+ const containerOpacityNum = isContainer === true ? nodeStyle?.opacity ?? 15 : void 0;
1910
1889
  const fillOpacityStyle = containerOpacityNum != null && isContainer === true ? `fillOpacity=${Math.min(100, Math.max(0, containerOpacityNum))};` : "";
1911
1890
  const likec4StyleWithBridge = buildLikec4StyleForNode({
1912
1891
  desc,
@@ -1971,17 +1950,17 @@ function buildNodeCellXml(data) {
1971
1950
  };
1972
1951
  return {
1973
1952
  vertexXml: cellXml,
1974
- titleCellXml: buildContainerTitleCellXml(data.title ?? "", data.titleCellId ?? data.id, data.navTo, data.id, data.fontFamily, data.containerTitleFontSizePx ?? 12, data.containerTitleColor ?? CONTAINER_TITLE_COLOR),
1953
+ titleCellXml: buildContainerTitleCellXml(data.title ?? "", data.titleCellId ?? data.id, data.navTo, data.id, data.fontFamily, data.containerTitleFontSizePx ?? 12, data.containerTitleColor ?? "#74c0fc"),
1975
1954
  isContainer: true
1976
1955
  };
1977
1956
  }
1978
1957
  /** Build container title cell XML (child of container, relative position CONTAINER_TITLE_INSET_*). */
1979
1958
  function buildContainerTitleCellXml(title, titleId, navTo, containerId, fontFamily, fontSizePx, colorHex) {
1980
1959
  const titleValue = escapeXml(title);
1981
- const titleWidth = Math.max(CONTAINER_TITLE_MIN_WIDTH_PX, Math.min(CONTAINER_TITLE_MAX_WIDTH_PX, title.length * CONTAINER_TITLE_CHAR_WIDTH_PX));
1982
- const titleHeight = CONTAINER_TITLE_HEIGHT_PX;
1983
- const titleX = CONTAINER_TITLE_INSET_X;
1984
- const titleY = CONTAINER_TITLE_INSET_Y;
1960
+ const titleWidth = Math.max(60, Math.min(260, title.length * 8));
1961
+ const titleHeight = 18;
1962
+ const titleX = 8;
1963
+ const titleY = 8;
1985
1964
  const navLinkStyle = buildNavLinkStyle(navTo);
1986
1965
  const titleStyle = `shape=text;html=1;fillColor=none;strokeColor=none;align=left;verticalAlign=top;fontSize=${fontSizePx};fontStyle=1;fontColor=${colorHex};fontFamily=${encodeURIComponent(fontFamily)};${navLinkStyle}`;
1987
1966
  if (navTo === "") return `<mxCell id="${titleId}" value="${titleValue}" style="${titleStyle}" vertex="1" parent="${containerId}">\n <mxGeometry x="${Math.round(titleX)}" y="${Math.round(titleY)}" width="${titleWidth}" height="${titleHeight}" as="geometry" />\n</mxCell>`;
@@ -2043,8 +2022,8 @@ function drawioArrow(arrow) {
2043
2022
  const DEFAULT_BBOX = {
2044
2023
  x: 0,
2045
2024
  y: 0,
2046
- width: DEFAULT_NODE_WIDTH,
2047
- height: DEFAULT_NODE_HEIGHT
2025
+ width: 120,
2026
+ height: 60
2048
2027
  };
2049
2028
  /** True when bbox equals default (unlaid) dimensions. */
2050
2029
  function isDefaultBbox(b) {
@@ -2071,7 +2050,7 @@ function spreadUnlaidNodesOverVertical(bboxes, sortedNodes, containerNodeIds) {
2071
2050
  bboxes.set(node.id, {
2072
2051
  ...firstBbox,
2073
2052
  x: firstBbox.x,
2074
- y: firstBbox.y + i * (firstBbox.height + NODES_SPREAD_GAP)
2053
+ y: firstBbox.y + i * (firstBbox.height + 24)
2075
2054
  });
2076
2055
  });
2077
2056
  }
@@ -2111,15 +2090,15 @@ function computeContentBoundsAndOffsets(bboxes) {
2111
2090
  }
2112
2091
  if (contentMinX === Infinity) contentMinX = 0;
2113
2092
  if (contentMinY === Infinity) contentMinY = 0;
2114
- if (contentMaxX === -Infinity) contentMaxX = contentMinX + DEFAULT_CANVAS_WIDTH;
2115
- if (contentMaxY === -Infinity) contentMaxY = contentMinY + DEFAULT_CANVAS_HEIGHT;
2093
+ if (contentMaxX === -Infinity) contentMaxX = contentMinX + 800;
2094
+ if (contentMaxY === -Infinity) contentMaxY = contentMinY + 600;
2116
2095
  const contentCx = contentMinX + (contentMaxX - contentMinX) / 2;
2117
2096
  const contentCy = contentMinY + (contentMaxY - contentMinY) / 2;
2118
2097
  return {
2119
- offsetX: DEFAULT_CANVAS_WIDTH / 2 - contentCx,
2120
- offsetY: DEFAULT_CANVAS_HEIGHT / 2 - contentCy,
2121
- canvasWidth: DEFAULT_CANVAS_WIDTH,
2122
- canvasHeight: DEFAULT_CANVAS_HEIGHT
2098
+ offsetX: 800 / 2 - contentCx,
2099
+ offsetY: 600 / 2 - contentCy,
2100
+ canvasWidth: 800,
2101
+ canvasHeight: 600
2123
2102
  };
2124
2103
  }
2125
2104
  /**
@@ -2146,8 +2125,8 @@ function computeDiagramLayout(viewmodel, options) {
2146
2125
  return {
2147
2126
  x: typeof d.x === "number" ? d.x : Array.isArray(d.position) ? d.position[0] : 0,
2148
2127
  y: typeof d.y === "number" ? d.y : Array.isArray(d.position) ? d.position[1] : 0,
2149
- width: typeof d.width === "number" ? d.width : d.size?.width ?? DEFAULT_NODE_WIDTH,
2150
- height: typeof d.height === "number" ? d.height : d.size?.height ?? DEFAULT_NODE_HEIGHT
2128
+ width: typeof d.width === "number" ? d.width : d.size?.width ?? 120,
2129
+ height: typeof d.height === "number" ? d.height : d.size?.height ?? 60
2151
2130
  };
2152
2131
  };
2153
2132
  const bboxes = /* @__PURE__ */ new Map();
@@ -2200,7 +2179,7 @@ function generateDiagramContent(viewmodel, options) {
2200
2179
  const getCellId = (nodeId) => {
2201
2180
  let id = nodeIds.get(nodeId);
2202
2181
  if (!id) {
2203
- if (cellId >= CONTAINER_TITLE_CELL_ID_START) throw new Error("DrawIO cell ID range exhausted");
2182
+ if (cellId >= 1e4) throw new Error("DrawIO cell ID range exhausted");
2204
2183
  id = String(cellId++);
2205
2184
  nodeIds.set(nodeId, id);
2206
2185
  }
@@ -2219,7 +2198,7 @@ function generateDiagramContent(viewmodel, options) {
2219
2198
  } else vertexCells.push(result.vertexXml);
2220
2199
  }
2221
2200
  for (const edge of edges) {
2222
- if (cellId >= CONTAINER_TITLE_CELL_ID_START) throw new Error("DrawIO cell ID range exhausted");
2201
+ if (cellId >= 1e4) throw new Error("DrawIO cell ID range exhausted");
2223
2202
  const edgeId = String(cellId++);
2224
2203
  edgeCells.push(buildEdgeCellXml(edge, layout, options, viewmodel, getCellId, edgeId));
2225
2204
  }
@@ -2232,7 +2211,7 @@ function generateDiagramContent(viewmodel, options) {
2232
2211
  ...edgeCells
2233
2212
  ].join("\n");
2234
2213
  const diagramName = (getViewTitle(view) ?? view.id).trim() || view.id;
2235
- const mxGraphModelXml = `<mxGraphModel dx="${MXGRAPH_DEFAULT_DX}" dy="${MXGRAPH_DEFAULT_DY}" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="${MXGRAPH_PAGE_WIDTH}" pageHeight="${MXGRAPH_PAGE_HEIGHT}" math="0" shadow="0">
2214
+ const mxGraphModelXml = `<mxGraphModel dx="800" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="${MXGRAPH_PAGE_HEIGHT}" math="0" shadow="0">
2236
2215
  <root>
2237
2216
  <mxCell id="${rootId}" />
2238
2217
  ${allCells}
@@ -2342,6 +2321,8 @@ function generateDrawioEditUrl(xml) {
2342
2321
  });
2343
2322
  return "https://app.diagrams.net/#create=" + encodeURIComponent(createObj);
2344
2323
  }
2324
+ //#endregion
2325
+ //#region src/mmd/generate-mmd.ts
2345
2326
  const capitalizeFirstLetter$1 = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
2346
2327
  const fqnName$1 = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter$1).join("");
2347
2328
  const nodeName$1 = (node) => {
@@ -2392,6 +2373,8 @@ function generateMermaid(viewmodel) {
2392
2373
  indentation: 2
2393
2374
  }));
2394
2375
  }
2376
+ //#endregion
2377
+ //#region src/model/generate-aux.ts
2395
2378
  function toUnion(elements) {
2396
2379
  if (elements.length === 0) return "never";
2397
2380
  return elements.sort(compareNatural).map((v) => ` | ${JSON.stringify(v)}`).join("\n").trimStart();
@@ -2444,6 +2427,8 @@ export type $Tags = readonly $Aux['Tag'][]
2444
2427
  export type $MetadataKey = $Aux['MetadataKey']
2445
2428
  `.trimStart();
2446
2429
  }
2430
+ //#endregion
2431
+ //#region src/model/generate-likec4-model.ts
2447
2432
  function generateLikeC4Model(model, options = {}) {
2448
2433
  const aux = generateAux(model, options);
2449
2434
  const { useCorePackage = false } = options;
@@ -2467,6 +2452,8 @@ export const likec4model: LikeC4Model<$Aux> = new LikeC4Model(${JSON5.stringify(
2467
2452
  /* prettier-ignore-end */
2468
2453
  `.trimStart();
2469
2454
  }
2455
+ //#endregion
2456
+ //#region src/puml/generate-puml.ts
2470
2457
  const capitalizeFirstLetter = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
2471
2458
  const fqnName = (nodeId) => {
2472
2459
  return nodeId.split(/[.-]/).map(capitalizeFirstLetter).join("");
@@ -2562,9 +2549,13 @@ function generatePuml(viewmodel) {
2562
2549
  };
2563
2550
  return toString(new CompositeGeneratorNode().append("@startuml", NL).append(printHeader(), NL).append(printTheme(), NL).append(joinToNode(nodes.filter((n) => n.children.length == 0), (n) => printStereotypes(n), { appendNewLineIfNotEmpty: true })).append(joinToNode(nodes.filter((n) => isNullish(n.parent)), (n) => n.children.length > 0 ? printBoundary(n) : printNode(n), { appendNewLineIfNotEmpty: true })).appendIf(edges.length > 0, NL, joinToNode(edges, (e) => printEdge(e), { appendNewLineIfNotEmpty: true })).append(`@enduml`, NL));
2564
2551
  }
2552
+ //#endregion
2553
+ //#region src/views-data-ts/generateViewId.ts
2565
2554
  function generateViewId(views) {
2566
2555
  return joinToNode(views, (view) => expandToNode`${JSON5.stringify(view.id)}`, { separator: " | " });
2567
2556
  }
2557
+ //#endregion
2558
+ //#region src/views-data-ts/generate-views-data.ts
2568
2559
  /**
2569
2560
  * Generate *.js file with views data
2570
2561
  */
@@ -2687,6 +2678,8 @@ function generateViewsDataDTs(diagrams) {
2687
2678
  `.append(NL);
2688
2679
  return toString(out);
2689
2680
  }
2681
+ //#endregion
2682
+ //#region src/react-next/generate-react-next.ts
2690
2683
  /**
2691
2684
  * @deprecated in favor packages/likec4/src/cli/codegen/react/index.ts
2692
2685
  */
@@ -2790,6 +2783,8 @@ function generateIndex() {
2790
2783
  dts: toString(dts)
2791
2784
  };
2792
2785
  }
2786
+ //#endregion
2787
+ //#region src/react/generate-react-types.ts
2793
2788
  function generateReactTypes(model, options = {}) {
2794
2789
  const { useCorePackage = false } = options;
2795
2790
  invariant$1(!model.isParsed(), "can not generate react types for parsed model");
@@ -2852,4 +2847,5 @@ export {
2852
2847
  /* prettier-ignore-end */
2853
2848
  `.trimStart();
2854
2849
  }
2850
+ //#endregion
2855
2851
  export { DEFAULT_DRAWIO_ALL_FILENAME, buildDrawioExportOptionsForViews, buildDrawioExportOptionsFromSource, decompressDrawioDiagram, generateD2, generateDrawio, generateDrawioEditUrl, generateDrawioMulti, generateLikeC4Model, generateMermaid, generatePuml, generateReactNext, generateReactTypes, generateViewsDataDTs, generateViewsDataJs, generateViewsDataTs, getAllDiagrams, parseDrawioRoundtripComments, parseDrawioToLikeC4, parseDrawioToLikeC4Multi };
@@ -9,6 +9,7 @@ import * as z$1 from "zod/v4";
9
9
  import { BorderStyles, ElementShapes, IconPositions, RelationshipArrowTypes, Sizes, ThemeColors } from "@likec4/core/styles";
10
10
  import { produce } from "immer";
11
11
  import { LikeC4StylesConfigSchema } from "@likec4/config";
12
+ //#region src/likec4/operators/base.ts
12
13
  var base_exports = /* @__PURE__ */ __exportAll({
13
14
  body: () => body,
14
15
  eachOnFresh: () => eachOnFresh,
@@ -527,6 +528,8 @@ function zodOp(schema) {
527
528
  };
528
529
  };
529
530
  }
531
+ //#endregion
532
+ //#region src/likec4/schemas/common.ts
530
533
  var common_exports = /* @__PURE__ */ __exportAll({
531
534
  arrow: () => arrow,
532
535
  border: () => border,
@@ -614,6 +617,8 @@ const props = z$1.object({
614
617
  links: links.nullable(),
615
618
  metadata
616
619
  }).partial();
620
+ //#endregion
621
+ //#region src/likec4/schemas/expression.ts
617
622
  var expression_exports = /* @__PURE__ */ __exportAll({
618
623
  directRelationExpr: () => directRelationExpr$1,
619
624
  elementKindExpr: () => elementKindExpr,
@@ -796,6 +801,8 @@ const expression$1 = z$1.union([
796
801
  relationExprCustom$1,
797
802
  whereExpr
798
803
  ]);
804
+ //#endregion
805
+ //#region src/likec4/schemas/deployment.ts
799
806
  var deployment_exports$1 = /* @__PURE__ */ __exportAll({
800
807
  element: () => element$3,
801
808
  instance: () => instance$1,
@@ -807,6 +814,11 @@ const node$1 = props.extend({
807
814
  id: fqn,
808
815
  kind,
809
816
  style: style.optional(),
817
+ /**
818
+ * Allowing shape, color and icon to be defined at the element level for convenience,
819
+ * they will be moved to the style property during parsing
820
+ * (and will override properties)
821
+ */
810
822
  shape: shape.optional(),
811
823
  color: color.optional(),
812
824
  icon: icon.optional()
@@ -824,6 +836,11 @@ const instance$1 = props.extend({
824
836
  id: fqn,
825
837
  element: fqn,
826
838
  style: style.optional(),
839
+ /**
840
+ * Allowing shape, color and icon to be defined at the element level for convenience,
841
+ * they will be moved to the style property during parsing
842
+ * (and will override properties)
843
+ */
827
844
  shape: shape.optional(),
828
845
  color: color.optional(),
829
846
  icon: icon.optional()
@@ -859,6 +876,8 @@ const schema$2 = z$1.object({
859
876
  elements: z$1.union([elements$1, z$1.array(element$3)]).transform((v) => isArray(v) ? indexBy(v, prop("id")) : v).optional(),
860
877
  relations: z$1.union([relationships$1, z$1.array(relationship$4)]).transform((v) => isArray(v) ? indexBy(v, genRelationshipId$1) : v).optional()
861
878
  });
879
+ //#endregion
880
+ //#region src/likec4/schemas/model.ts
862
881
  var model_exports$1 = /* @__PURE__ */ __exportAll({
863
882
  element: () => element$2,
864
883
  relationship: () => relationship$3,
@@ -873,6 +892,11 @@ const element$2 = z$1.object({
873
892
  id: fqn,
874
893
  kind,
875
894
  style: style.optional(),
895
+ /**
896
+ * Allowing shape, color and icon to be defined at the element level for convenience,
897
+ * they will be moved to the style property during parsing
898
+ * (and will override properties)
899
+ */
876
900
  shape: shape.optional(),
877
901
  color: color.optional(),
878
902
  icon: icon.optional()
@@ -908,6 +932,8 @@ const schema$1 = z$1.object({
908
932
  elements: z$1.union([elements, z$1.array(element$2)]).transform((v) => isArray(v) ? indexBy(v, prop("id")) : v).optional(),
909
933
  relations: z$1.union([relationships, z$1.array(relationship$3)]).transform((v) => isArray(v) ? indexBy(v, genRelationshipId) : v).optional()
910
934
  });
935
+ //#endregion
936
+ //#region src/likec4/schemas/specification.ts
911
937
  var specification_exports$1 = /* @__PURE__ */ __exportAll({
912
938
  element: () => element$1,
913
939
  relationship: () => relationship$2,
@@ -942,11 +968,26 @@ const relationship$2 = z$1.object({
942
968
  }).partial().transform(pickBy(isNonNullish));
943
969
  const tagSpec = z$1.object({ color: z$1.string().regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).optional().catch(void 0) }).partial().transform(pickBy(isNonNullish));
944
970
  const schema = z$1.object({
971
+ /**
972
+ * Element kinds specifications, where key is the kind name
973
+ */
945
974
  elements: z$1.record(kind, element$1),
975
+ /**
976
+ * Element kinds specifications, where key is the kind name
977
+ */
946
978
  deployments: z$1.record(kind, element$1),
979
+ /**
980
+ * Relationship kinds specifications, where key is the kind name
981
+ */
947
982
  relationships: z$1.record(kind, relationship$2),
983
+ /**
984
+ * Tag specifications, where key is the tag name
985
+ * Or an array of tags, if no additional properties are needed for tags (like color)
986
+ */
948
987
  tags: z$1.union([z$1.record(tag, tagSpec), z$1.array(tag).transform((tags) => mapToObj(tags, (t) => [t, {}]))])
949
988
  }).partial();
989
+ //#endregion
990
+ //#region src/likec4/schemas/views.ts
950
991
  var views_exports$1 = /* @__PURE__ */ __exportAll({
951
992
  anyView: () => anyView$1,
952
993
  autoLayoutDirection: () => autoLayoutDirection,
@@ -1150,6 +1191,8 @@ function normalizeElementStyles(element, specs) {
1150
1191
  for (const [key, value] of entries(specStyle)) if (isDeepEqual(element.style?.[key], value)) delete draft.style[key];
1151
1192
  });
1152
1193
  }
1194
+ //#endregion
1195
+ //#region src/likec4/schemas/index.ts
1153
1196
  const schemas = {
1154
1197
  common: common_exports,
1155
1198
  expr: expression_exports,
@@ -1159,6 +1202,8 @@ const schemas = {
1159
1202
  views: views_exports$1,
1160
1203
  likec4data: likec4data$1
1161
1204
  };
1205
+ //#endregion
1206
+ //#region src/likec4/operators/properties.ts
1162
1207
  var properties_exports = /* @__PURE__ */ __exportAll({
1163
1208
  colorProperty: () => colorProperty,
1164
1209
  descriptionProperty: () => descriptionProperty,
@@ -1239,6 +1284,8 @@ function iconProperty() {
1239
1284
  return property("icon", spaceBetween(print$1("icon"), print$1()));
1240
1285
  }
1241
1286
  const styleProperties = zodOp(style)(lines(property("shape"), colorProperty(), iconProperty(), property("iconColor"), property("iconSize"), property("iconPosition"), property("border"), opacityProperty(), property("size"), property("padding"), property("textSize"), property("multiple")));
1287
+ //#endregion
1288
+ //#region src/likec4/operators/expressions.ts
1242
1289
  var expressions_exports = /* @__PURE__ */ __exportAll({
1243
1290
  directRelationExpr: () => directRelationExpr,
1244
1291
  expression: () => expression,
@@ -1454,6 +1501,8 @@ const expression = zodOp(expression$1)(({ ctx, exec }) => {
1454
1501
  }
1455
1502
  nonexhaustive(ctx);
1456
1503
  });
1504
+ //#endregion
1505
+ //#region src/likec4/operators/deployment.ts
1457
1506
  var deployment_exports = /* @__PURE__ */ __exportAll({
1458
1507
  deployment: () => deployment,
1459
1508
  instance: () => instance,
@@ -1528,6 +1577,8 @@ function hasRelationProps$1(rel) {
1528
1577
  }
1529
1578
  const relationship$1 = zodOp(schemas.deployment.relationship)(spaceBetween(property("source", fqnRef()), print$1((rel) => rel.kind ? `-[${rel.kind}]->` : "->"), property("target", fqnRef()), property("title", inlineText()), when(hasRelationProps$1, body(tagsProperty(), technologyProperty(), summaryProperty(), descriptionProperty(), property("navigateTo"), linksProperty(), metadataProperty(), when(hasRelationStyle$1, body("style")(colorProperty(), property("line"), property("head"), property("tail")))))));
1530
1579
  const deployment = zodOp(schemas.deployment.schema)(body("deployment")(lines(2)(select((d) => buildTree$1(d.elements ? values(d.elements) : []).roots, lines(2)(foreach(node()))), select((d) => d.relations ? values(d.relations) : void 0, lines(2)(foreach(relationship$1()))))));
1580
+ //#endregion
1581
+ //#region src/likec4/operators/model.ts
1531
1582
  var model_exports = /* @__PURE__ */ __exportAll({
1532
1583
  element: () => element,
1533
1584
  model: () => model,
@@ -1588,6 +1639,8 @@ function hasRelationProps(rel) {
1588
1639
  const relationship = zodOp(schemas.model.relationship)(spaceBetween(property("source", fqnRef()), print$1((rel) => rel.kind ? `-[${rel.kind}]->` : "->"), property("target", fqnRef()), property("title", inlineText()), when(hasRelationProps, body(tagsProperty(), technologyProperty(), summaryProperty(), descriptionProperty(), property("navigateTo"), linksProperty(), metadataProperty(), when(hasRelationStyle, body("style")(colorProperty(), property("line"), property("head"), property("tail")))))));
1589
1640
  const element = zodOp(schemas.model.element)(elementTree());
1590
1641
  const model = zodOp(schemas.model.schema)(body("model")(lines(2)(select((d) => buildTree(d.elements ? values(d.elements) : []).roots, lines(2)(foreach(elementTree()))), select((d) => d.relations ? values(d.relations) : void 0, lines(2)(foreach(relationship()))))));
1642
+ //#endregion
1643
+ //#region src/likec4/operators/specification.ts
1591
1644
  var specification_exports = /* @__PURE__ */ __exportAll({
1592
1645
  elementKind: () => elementKind,
1593
1646
  relationshipKind: () => relationshipKind,
@@ -1598,6 +1651,8 @@ const tagSpecification = zodOp(z$1.tuple([z$1.string(), tagSpec]))(spaceBetween(
1598
1651
  const elementKind = (keyword) => zodOp(z$1.tuple([z$1.string(), element$1]))(spaceBetween(print$1(keyword), printProperty("0"), property("1", body(tagsProperty(), titleProperty(), summaryProperty(), descriptionProperty(), technologyProperty(), notationProperty(), linksProperty(), property("style", body("style")(styleProperties()))))));
1599
1652
  const relationshipKind = zodOp(z$1.tuple([z$1.string(), relationship$2]))(spaceBetween(print$1("relationship"), printProperty("0"), property("1", body(technologyProperty(), notationProperty(), colorProperty(), property("line"), property("head"), property("tail")))));
1600
1653
  const specification = zodOp(schema)(body("specification")(lines(2)(select((c) => c.elements && entries(c.elements), foreachNewLine(elementKind("element")())), select((c) => c.deployments && entries(c.deployments), foreachNewLine(elementKind("deploymentNode")())), select((c) => c.relationships && entries(c.relationships), foreachNewLine(relationshipKind())), select((c) => c.tags && entries(c.tags), foreachNewLine(tagSpecification())))));
1654
+ //#endregion
1655
+ //#region src/likec4/operators/views.ts
1601
1656
  var views_exports = /* @__PURE__ */ __exportAll({
1602
1657
  anyView: () => anyView,
1603
1658
  deploymentView: () => deploymentView,
@@ -1716,8 +1771,12 @@ const views = zodOp(schemas.views.views)(body("views")(select((ctx) => values(ct
1716
1771
  separator: new CompositeGeneratorNode().appendNewLine().appendNewLine(),
1717
1772
  prefix: (_, index, isLast) => index === 0 && !isLast ? NL : void 0
1718
1773
  }))));
1774
+ //#endregion
1775
+ //#region src/likec4/operators/likec4data.ts
1719
1776
  z$1.object({});
1720
1777
  const likec4data = zodOp(schemas.likec4data)(lines(2)(property("specification", specification()), model(), property("deployment", deployment()), property("deployments", deployment()), property("views", views())));
1778
+ //#endregion
1779
+ //#region src/likec4/operators/index.ts
1721
1780
  var operators_exports = /* @__PURE__ */ __exportAll({
1722
1781
  base: () => base_exports,
1723
1782
  deployment: () => deployment,
@@ -1735,6 +1794,8 @@ var operators_exports = /* @__PURE__ */ __exportAll({
1735
1794
  specifications: () => specification_exports,
1736
1795
  views: () => views_exports
1737
1796
  });
1797
+ //#endregion
1798
+ //#region src/likec4/generate-likec4.ts
1738
1799
  function generateLikeC4(input, params) {
1739
1800
  params = {
1740
1801
  indentation: 2,
@@ -1795,4 +1856,5 @@ function print(operator, data, params) {
1795
1856
  function printTabIndent(operator, data) {
1796
1857
  return materialize(withctx(data, operator()), " ");
1797
1858
  }
1859
+ //#endregion
1798
1860
  export { generateLikeC4 as generate, operators_exports as operators, print, printTabIndent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/generators",
3
- "version": "1.55.0",
3
+ "version": "1.56.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -54,18 +54,18 @@
54
54
  "indent-string": "^5.0.0",
55
55
  "strip-indent": "^4.1.1",
56
56
  "zod": "^4.3.6",
57
- "@likec4/core": "1.55.0",
58
- "@likec4/config": "1.55.0",
59
- "@likec4/log": "1.55.0"
57
+ "@likec4/core": "1.56.0",
58
+ "@likec4/config": "1.56.0",
59
+ "@likec4/log": "1.56.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@types/node": "~22.19.15",
62
+ "@types/node": "~22.19.17",
63
63
  "@types/pako": "^2.0.4",
64
64
  "typescript": "5.9.3",
65
65
  "obuild": "0.4.31",
66
66
  "vitest": "4.1.3",
67
- "@likec4/tsconfig": "1.55.0",
68
- "@likec4/devops": "1.42.0"
67
+ "@likec4/devops": "1.42.0",
68
+ "@likec4/tsconfig": "1.56.0"
69
69
  },
70
70
  "scripts": {
71
71
  "typecheck": "tsc -b --verbose",