mermaiden 3.0.0__tar.gz

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.
Files changed (348) hide show
  1. mermaiden-3.0.0/.gitignore +11 -0
  2. mermaiden-3.0.0/.node-version +1 -0
  3. mermaiden-3.0.0/PKG-INFO +79 -0
  4. mermaiden-3.0.0/README.md +49 -0
  5. mermaiden-3.0.0/pyproject.toml +70 -0
  6. mermaiden-3.0.0/src/mermaiden/README.md +56 -0
  7. mermaiden-3.0.0/src/mermaiden/__init__.py +0 -0
  8. mermaiden-3.0.0/src/mermaiden/_version.py +24 -0
  9. mermaiden-3.0.0/src/mermaiden/application.py +98 -0
  10. mermaiden-3.0.0/src/mermaiden/core/__init__.py +34 -0
  11. mermaiden-3.0.0/src/mermaiden/core/annotation.py +25 -0
  12. mermaiden-3.0.0/src/mermaiden/core/constraint.py +109 -0
  13. mermaiden-3.0.0/src/mermaiden/core/diagram.py +68 -0
  14. mermaiden-3.0.0/src/mermaiden/core/element.py +18 -0
  15. mermaiden-3.0.0/src/mermaiden/core/error.py +2 -0
  16. mermaiden-3.0.0/src/mermaiden/core/relation.py +8 -0
  17. mermaiden-3.0.0/src/mermaiden/diagrams/__init__.py +0 -0
  18. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/__init__.py +0 -0
  19. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/annotations.py +24 -0
  20. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/constraints.py +27 -0
  21. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/diagram.py +45 -0
  22. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/elements.py +20 -0
  23. mermaiden-3.0.0/src/mermaiden/diagrams/architecture/relations.py +27 -0
  24. mermaiden-3.0.0/src/mermaiden/diagrams/base.py +74 -0
  25. mermaiden-3.0.0/src/mermaiden/diagrams/block/__init__.py +0 -0
  26. mermaiden-3.0.0/src/mermaiden/diagrams/block/configuration.py +9 -0
  27. mermaiden-3.0.0/src/mermaiden/diagrams/block/constraints/__init__.py +0 -0
  28. mermaiden-3.0.0/src/mermaiden/diagrams/block/constraints/constraint.py +7 -0
  29. mermaiden-3.0.0/src/mermaiden/diagrams/block/constraints/members.py +21 -0
  30. mermaiden-3.0.0/src/mermaiden/diagrams/block/constraints/structure.py +14 -0
  31. mermaiden-3.0.0/src/mermaiden/diagrams/block/diagram.py +39 -0
  32. mermaiden-3.0.0/src/mermaiden/diagrams/block/elements.py +23 -0
  33. mermaiden-3.0.0/src/mermaiden/diagrams/block/relations.py +0 -0
  34. mermaiden-3.0.0/src/mermaiden/diagrams/c4/__init__.py +0 -0
  35. mermaiden-3.0.0/src/mermaiden/diagrams/c4/configuration.py +7 -0
  36. mermaiden-3.0.0/src/mermaiden/diagrams/c4/constraints/__init__.py +0 -0
  37. mermaiden-3.0.0/src/mermaiden/diagrams/c4/constraints/constraint.py +7 -0
  38. mermaiden-3.0.0/src/mermaiden/diagrams/c4/constraints/members.py +22 -0
  39. mermaiden-3.0.0/src/mermaiden/diagrams/c4/constraints/structure.py +39 -0
  40. mermaiden-3.0.0/src/mermaiden/diagrams/c4/diagram.py +42 -0
  41. mermaiden-3.0.0/src/mermaiden/diagrams/c4/elements.py +30 -0
  42. mermaiden-3.0.0/src/mermaiden/diagrams/c4/relations.py +10 -0
  43. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/__init__.py +0 -0
  44. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/annotations.py +30 -0
  45. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/constraints.py +47 -0
  46. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/diagram.py +60 -0
  47. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/elements.py +49 -0
  48. mermaiden-3.0.0/src/mermaiden/diagrams/classdiagram/relations.py +30 -0
  49. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/__init__.py +0 -0
  50. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/configuration.py +21 -0
  51. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/constraints/__init__.py +0 -0
  52. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/constraints/constraint.py +7 -0
  53. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/constraints/members.py +22 -0
  54. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/constraints/structure.py +31 -0
  55. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/diagram.py +33 -0
  56. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/elements.py +19 -0
  57. mermaiden-3.0.0/src/mermaiden/diagrams/cynefin/relations.py +9 -0
  58. mermaiden-3.0.0/src/mermaiden/diagrams/er/__init__.py +0 -0
  59. mermaiden-3.0.0/src/mermaiden/diagrams/er/configuration.py +27 -0
  60. mermaiden-3.0.0/src/mermaiden/diagrams/er/constraints/__init__.py +0 -0
  61. mermaiden-3.0.0/src/mermaiden/diagrams/er/constraints/constraint.py +7 -0
  62. mermaiden-3.0.0/src/mermaiden/diagrams/er/constraints/members.py +22 -0
  63. mermaiden-3.0.0/src/mermaiden/diagrams/er/constraints/structure.py +14 -0
  64. mermaiden-3.0.0/src/mermaiden/diagrams/er/diagram.py +65 -0
  65. mermaiden-3.0.0/src/mermaiden/diagrams/er/elements.py +18 -0
  66. mermaiden-3.0.0/src/mermaiden/diagrams/er/relations.py +10 -0
  67. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/__init__.py +0 -0
  68. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/configuration.py +7 -0
  69. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/constraints/__init__.py +0 -0
  70. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/constraints/constraint.py +7 -0
  71. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/constraints/members.py +22 -0
  72. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/constraints/structure.py +33 -0
  73. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/diagram.py +48 -0
  74. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/elements.py +30 -0
  75. mermaiden-3.0.0/src/mermaiden/diagrams/eventmodeling/relations.py +10 -0
  76. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/__init__.py +0 -0
  77. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/annotations.py +31 -0
  78. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/__init__.py +0 -0
  79. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/conditional_flows_have_conditions.py +26 -0
  80. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/constraint.py +8 -0
  81. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/decision_branches_are_conditioned.py +35 -0
  82. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/every_node_is_reachable.py +34 -0
  83. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/exactly_one_start.py +18 -0
  84. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/flow_endpoints_are_nodes.py +30 -0
  85. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/flowchart_contains_only_flowchart_members.py +23 -0
  86. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/flows_are_binary.py +25 -0
  87. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/node_degree_rules.py +74 -0
  88. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/constraints/notes_are_valid.py +36 -0
  89. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/diagram.py +120 -0
  90. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/elements.py +68 -0
  91. mermaiden-3.0.0/src/mermaiden/diagrams/flowchart/relations.py +26 -0
  92. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/__init__.py +0 -0
  93. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/configuration.py +35 -0
  94. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/constraints/__init__.py +0 -0
  95. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/constraints/constraint.py +7 -0
  96. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/constraints/members.py +21 -0
  97. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/constraints/structure.py +14 -0
  98. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/diagram.py +46 -0
  99. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/elements.py +27 -0
  100. mermaiden-3.0.0/src/mermaiden/diagrams/gantt/relations.py +2 -0
  101. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/__init__.py +0 -0
  102. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/configuration.py +40 -0
  103. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/constraints/__init__.py +0 -0
  104. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/constraints/constraint.py +7 -0
  105. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/constraints/members.py +22 -0
  106. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/constraints/structure.py +48 -0
  107. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/diagram.py +35 -0
  108. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/elements.py +22 -0
  109. mermaiden-3.0.0/src/mermaiden/diagrams/gitgraph/relations.py +10 -0
  110. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/__init__.py +0 -0
  111. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/configuration.py +7 -0
  112. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/constraints/__init__.py +0 -0
  113. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/constraints/constraint.py +7 -0
  114. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/constraints/members.py +22 -0
  115. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/constraints/structure.py +31 -0
  116. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/diagram.py +35 -0
  117. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/elements.py +20 -0
  118. mermaiden-3.0.0/src/mermaiden/diagrams/ishikawa/relations.py +10 -0
  119. mermaiden-3.0.0/src/mermaiden/diagrams/journey/__init__.py +0 -0
  120. mermaiden-3.0.0/src/mermaiden/diagrams/journey/diagram.py +62 -0
  121. mermaiden-3.0.0/src/mermaiden/diagrams/journey/elements.py +16 -0
  122. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/__init__.py +0 -0
  123. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/configuration.py +15 -0
  124. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/constraints/__init__.py +0 -0
  125. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/constraints/constraint.py +7 -0
  126. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/constraints/members.py +21 -0
  127. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/constraints/structure.py +38 -0
  128. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/diagram.py +44 -0
  129. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/elements.py +17 -0
  130. mermaiden-3.0.0/src/mermaiden/diagrams/kanban/relations.py +2 -0
  131. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/__init__.py +0 -0
  132. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/configuration.py +17 -0
  133. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/constraints/__init__.py +0 -0
  134. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/constraints/constraint.py +7 -0
  135. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/constraints/exactly_one_root.py +18 -0
  136. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/constraints/mindmap_contains_only_mindmap_members.py +21 -0
  137. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/diagram.py +53 -0
  138. mermaiden-3.0.0/src/mermaiden/diagrams/mindmap/elements.py +39 -0
  139. mermaiden-3.0.0/src/mermaiden/diagrams/packet/__init__.py +0 -0
  140. mermaiden-3.0.0/src/mermaiden/diagrams/packet/configuration.py +21 -0
  141. mermaiden-3.0.0/src/mermaiden/diagrams/packet/constraints/__init__.py +0 -0
  142. mermaiden-3.0.0/src/mermaiden/diagrams/packet/constraints/constraint.py +7 -0
  143. mermaiden-3.0.0/src/mermaiden/diagrams/packet/constraints/members.py +21 -0
  144. mermaiden-3.0.0/src/mermaiden/diagrams/packet/constraints/structure.py +26 -0
  145. mermaiden-3.0.0/src/mermaiden/diagrams/packet/diagram.py +36 -0
  146. mermaiden-3.0.0/src/mermaiden/diagrams/packet/elements.py +12 -0
  147. mermaiden-3.0.0/src/mermaiden/diagrams/packet/relations.py +0 -0
  148. mermaiden-3.0.0/src/mermaiden/diagrams/pie/__init__.py +0 -0
  149. mermaiden-3.0.0/src/mermaiden/diagrams/pie/configuration.py +26 -0
  150. mermaiden-3.0.0/src/mermaiden/diagrams/pie/constraints/__init__.py +0 -0
  151. mermaiden-3.0.0/src/mermaiden/diagrams/pie/constraints/constraint.py +7 -0
  152. mermaiden-3.0.0/src/mermaiden/diagrams/pie/constraints/pie_contains_only_pie_members.py +21 -0
  153. mermaiden-3.0.0/src/mermaiden/diagrams/pie/constraints/slices_are_positive.py +23 -0
  154. mermaiden-3.0.0/src/mermaiden/diagrams/pie/diagram.py +37 -0
  155. mermaiden-3.0.0/src/mermaiden/diagrams/pie/elements.py +10 -0
  156. mermaiden-3.0.0/src/mermaiden/diagrams/radar/__init__.py +0 -0
  157. mermaiden-3.0.0/src/mermaiden/diagrams/radar/configuration.py +27 -0
  158. mermaiden-3.0.0/src/mermaiden/diagrams/radar/constraints/__init__.py +0 -0
  159. mermaiden-3.0.0/src/mermaiden/diagrams/radar/constraints/constraint.py +7 -0
  160. mermaiden-3.0.0/src/mermaiden/diagrams/radar/constraints/members.py +21 -0
  161. mermaiden-3.0.0/src/mermaiden/diagrams/radar/constraints/structure.py +27 -0
  162. mermaiden-3.0.0/src/mermaiden/diagrams/radar/diagram.py +54 -0
  163. mermaiden-3.0.0/src/mermaiden/diagrams/radar/elements.py +15 -0
  164. mermaiden-3.0.0/src/mermaiden/diagrams/radar/relations.py +0 -0
  165. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/__init__.py +0 -0
  166. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/configuration.py +23 -0
  167. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/constraints/__init__.py +0 -0
  168. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/constraints/constraint.py +7 -0
  169. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/constraints/members.py +21 -0
  170. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/constraints/structure.py +22 -0
  171. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/diagram.py +51 -0
  172. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/elements.py +44 -0
  173. mermaiden-3.0.0/src/mermaiden/diagrams/railroad/relations.py +2 -0
  174. mermaiden-3.0.0/src/mermaiden/diagrams/registry.py +64 -0
  175. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/__init__.py +0 -0
  176. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/configuration.py +29 -0
  177. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/constraints/__init__.py +0 -0
  178. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/constraints/constraint.py +10 -0
  179. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/constraints/relations_are_valid.py +38 -0
  180. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/constraints/requirement_contains_only_requirement_members.py +22 -0
  181. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/diagram.py +62 -0
  182. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/elements.py +44 -0
  183. mermaiden-3.0.0/src/mermaiden/diagrams/requirement/relations.py +29 -0
  184. mermaiden-3.0.0/src/mermaiden/diagrams/sankey/__init__.py +0 -0
  185. mermaiden-3.0.0/src/mermaiden/diagrams/sankey/diagram.py +58 -0
  186. mermaiden-3.0.0/src/mermaiden/diagrams/sankey/elements.py +9 -0
  187. mermaiden-3.0.0/src/mermaiden/diagrams/sankey/relations.py +18 -0
  188. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/__init__.py +0 -0
  189. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/annotations.py +40 -0
  190. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/constraints.py +27 -0
  191. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/diagram.py +96 -0
  192. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/elements.py +29 -0
  193. mermaiden-3.0.0/src/mermaiden/diagrams/sequence/relations.py +64 -0
  194. mermaiden-3.0.0/src/mermaiden/diagrams/state/__init__.py +0 -0
  195. mermaiden-3.0.0/src/mermaiden/diagrams/state/annotations.py +41 -0
  196. mermaiden-3.0.0/src/mermaiden/diagrams/state/configuration.py +22 -0
  197. mermaiden-3.0.0/src/mermaiden/diagrams/state/constraints/__init__.py +0 -0
  198. mermaiden-3.0.0/src/mermaiden/diagrams/state/constraints/constraint.py +10 -0
  199. mermaiden-3.0.0/src/mermaiden/diagrams/state/constraints/notes_are_valid.py +29 -0
  200. mermaiden-3.0.0/src/mermaiden/diagrams/state/constraints/state_contains_only_state_members.py +23 -0
  201. mermaiden-3.0.0/src/mermaiden/diagrams/state/constraints/transitions_are_valid.py +38 -0
  202. mermaiden-3.0.0/src/mermaiden/diagrams/state/diagram.py +107 -0
  203. mermaiden-3.0.0/src/mermaiden/diagrams/state/elements.py +45 -0
  204. mermaiden-3.0.0/src/mermaiden/diagrams/state/relations.py +20 -0
  205. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/__init__.py +0 -0
  206. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/configuration.py +23 -0
  207. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/__init__.py +0 -0
  208. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/constraint.py +10 -0
  209. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/flow_endpoints_are_nodes.py +33 -0
  210. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/flows_are_binary.py +25 -0
  211. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/lanes_are_top_level.py +24 -0
  212. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/nodes_belong_to_lanes.py +23 -0
  213. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/constraints/swimlane_contains_only_swimlane_members.py +22 -0
  214. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/diagram.py +62 -0
  215. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/elements.py +39 -0
  216. mermaiden-3.0.0/src/mermaiden/diagrams/swimlane/relations.py +26 -0
  217. mermaiden-3.0.0/src/mermaiden/diagrams/timeline/__init__.py +0 -0
  218. mermaiden-3.0.0/src/mermaiden/diagrams/timeline/diagram.py +65 -0
  219. mermaiden-3.0.0/src/mermaiden/diagrams/timeline/elements.py +19 -0
  220. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/__init__.py +0 -0
  221. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/annotations.py +38 -0
  222. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/__init__.py +0 -0
  223. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/annotations_are_valid.py +38 -0
  224. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/branches_are_acyclic.py +42 -0
  225. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/branches_are_valid.py +45 -0
  226. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/constraint.py +10 -0
  227. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/constraints/treeview_contains_only_treeview_members.py +23 -0
  228. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/diagram.py +54 -0
  229. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/elements.py +9 -0
  230. mermaiden-3.0.0/src/mermaiden/diagrams/treeview/relations.py +17 -0
  231. mermaiden-3.0.0/src/mermaiden/diagrams/venn/__init__.py +0 -0
  232. mermaiden-3.0.0/src/mermaiden/diagrams/venn/configuration.py +17 -0
  233. mermaiden-3.0.0/src/mermaiden/diagrams/venn/constraints/__init__.py +0 -0
  234. mermaiden-3.0.0/src/mermaiden/diagrams/venn/constraints/constraint.py +7 -0
  235. mermaiden-3.0.0/src/mermaiden/diagrams/venn/constraints/members.py +21 -0
  236. mermaiden-3.0.0/src/mermaiden/diagrams/venn/constraints/structure.py +28 -0
  237. mermaiden-3.0.0/src/mermaiden/diagrams/venn/diagram.py +41 -0
  238. mermaiden-3.0.0/src/mermaiden/diagrams/venn/elements.py +22 -0
  239. mermaiden-3.0.0/src/mermaiden/diagrams/venn/relations.py +0 -0
  240. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/__init__.py +0 -0
  241. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/configuration.py +7 -0
  242. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/constraints/__init__.py +0 -0
  243. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/constraints/constraint.py +7 -0
  244. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/constraints/members.py +22 -0
  245. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/constraints/structure.py +36 -0
  246. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/diagram.py +41 -0
  247. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/elements.py +24 -0
  248. mermaiden-3.0.0/src/mermaiden/diagrams/wardley/relations.py +10 -0
  249. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/__init__.py +3 -0
  250. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/configuration.py +86 -0
  251. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/parser.py +89 -0
  252. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/schema.lock.json +5 -0
  253. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/schema.py +56 -0
  254. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/schemas/config.schema.json +3614 -0
  255. mermaiden-3.0.0/src/mermaiden/mermaid/compatibility/service.py +98 -0
  256. mermaiden-3.0.0/src/mermaiden/mermaid/fixtures.py +495 -0
  257. mermaiden-3.0.0/src/mermaiden/mermaid/preview.py +50 -0
  258. mermaiden-3.0.0/src/mermaiden/mermaid/service.py +85 -0
  259. mermaiden-3.0.0/src/mermaiden/mermaid/templates/macros/document.mmd.j2 +28 -0
  260. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/C4Context/document.mmd.j2 +3 -0
  261. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/architecture-beta/annotations/architecture_note.mmd.j2 +1 -0
  262. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/architecture-beta/document.mmd.j2 +5 -0
  263. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/architecture-beta/elements/architecture_group.mmd.j2 +3 -0
  264. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/architecture-beta/elements/member.mmd.j2 +1 -0
  265. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/architecture-beta/relations/edge.mmd.j2 +1 -0
  266. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/block/document.mmd.j2 +8 -0
  267. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/classDiagram/annotations/class_note.mmd.j2 +1 -0
  268. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/classDiagram/document.mmd.j2 +5 -0
  269. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/classDiagram/elements/class.mmd.j2 +12 -0
  270. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/classDiagram/elements/class_namespace.mmd.j2 +5 -0
  271. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/classDiagram/relations/class_relation.mmd.j2 +1 -0
  272. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/cynefin-beta/document.mmd.j2 +3 -0
  273. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/erDiagram/document.mmd.j2 +6 -0
  274. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/eventmodeling/document.mmd.j2 +4 -0
  275. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/flowchart/annotations/note.mmd.j2 +4 -0
  276. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/flowchart/document.mmd.j2 +5 -0
  277. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/flowchart/elements/flow_group.mmd.j2 +7 -0
  278. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/flowchart/elements/node.mmd.j2 +2 -0
  279. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/flowchart/relations/relation.mmd.j2 +1 -0
  280. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/gantt/document.mmd.j2 +3 -0
  281. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/gitGraph/document.mmd.j2 +5 -0
  282. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/ishikawa-beta/document.mmd.j2 +6 -0
  283. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/journey/document.mmd.j2 +3 -0
  284. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/kanban/document.mmd.j2 +2 -0
  285. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/document.mmd.j2 +3 -0
  286. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/bang.mmd.j2 +3 -0
  287. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/circle.mmd.j2 +3 -0
  288. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/cloud.mmd.j2 +3 -0
  289. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/hexagon.mmd.j2 +3 -0
  290. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/mindmap_node.mmd.j2 +3 -0
  291. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/rounded_square.mmd.j2 +3 -0
  292. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/mindmap/elements/square.mmd.j2 +3 -0
  293. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/packet/document.mmd.j2 +2 -0
  294. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/pie/document.mmd.j2 +3 -0
  295. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/radar-beta/document.mmd.j2 +6 -0
  296. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/railroad-ebnf-beta/document.mmd.j2 +3 -0
  297. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/requirementDiagram/document.mmd.j2 +4 -0
  298. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/requirementDiagram/elements/requirement.mmd.j2 +6 -0
  299. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/requirementDiagram/elements/requirement_element.mmd.j2 +4 -0
  300. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/requirementDiagram/relations/requirement_relation.mmd.j2 +1 -0
  301. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sankey/document.mmd.j2 +2 -0
  302. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/annotations/sequence_note.mmd.j2 +1 -0
  303. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/document.mmd.j2 +5 -0
  304. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/elements/participant.mmd.j2 +2 -0
  305. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/elements/participant_box.mmd.j2 +3 -0
  306. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/macros/participant.mmd.j2 +3 -0
  307. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/relations/event.mmd.j2 +2 -0
  308. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/sequenceDiagram/relations/message.mmd.j2 +1 -0
  309. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/annotations/state_note.mmd.j2 +1 -0
  310. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/document.mmd.j2 +22 -0
  311. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/choice.mmd.j2 +1 -0
  312. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/final.mmd.j2 +0 -0
  313. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/fork.mmd.j2 +1 -0
  314. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/initial.mmd.j2 +0 -0
  315. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/join.mmd.j2 +1 -0
  316. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/elements/state.mmd.j2 +1 -0
  317. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/stateDiagram-v2/relations/state_transition.mmd.j2 +1 -0
  318. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/swimlane-beta/document.mmd.j2 +4 -0
  319. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/swimlane-beta/elements/node.mmd.j2 +2 -0
  320. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/swimlane-beta/elements/swimlane.mmd.j2 +4 -0
  321. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/swimlane-beta/relations/relation.mmd.j2 +1 -0
  322. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/timeline/document.mmd.j2 +13 -0
  323. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/treeView-beta/document.mmd.j2 +2 -0
  324. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/treeView-beta/elements/tree_item.mmd.j2 +1 -0
  325. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/venn-beta/document.mmd.j2 +3 -0
  326. mermaiden-3.0.0/src/mermaiden/mermaid/templates/syntax/wardley-beta/document.mmd.j2 +4 -0
  327. mermaiden-3.0.0/src/mermaiden/runtime/__init__.py +0 -0
  328. mermaiden-3.0.0/src/mermaiden/runtime/constraints/__init__.py +0 -0
  329. mermaiden-3.0.0/src/mermaiden/runtime/constraints/annotations_have_targets.py +20 -0
  330. mermaiden-3.0.0/src/mermaiden/runtime/constraints/elements_exist.py +15 -0
  331. mermaiden-3.0.0/src/mermaiden/runtime/constraints/identities_are_valid.py +38 -0
  332. mermaiden-3.0.0/src/mermaiden/runtime/constraints/labels_are_present.py +20 -0
  333. mermaiden-3.0.0/src/mermaiden/runtime/constraints/references_exist.py +38 -0
  334. mermaiden-3.0.0/src/mermaiden/runtime/constraints/relations_have_participants.py +20 -0
  335. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/__init__.py +0 -0
  336. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/aggregate.py +162 -0
  337. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/annotations.py +50 -0
  338. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/elements.py +80 -0
  339. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/observer.py +24 -0
  340. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/relations.py +34 -0
  341. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/runtime.py +22 -0
  342. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/state.py +34 -0
  343. mermaiden-3.0.0/src/mermaiden/runtime/diagrams/transaction.py +52 -0
  344. mermaiden-3.0.0/tests/mermaiden/test_diagram_registry.py +73 -0
  345. mermaiden-3.0.0/tests/mermaiden/test_mermaid_compatibility.py +118 -0
  346. mermaiden-3.0.0/tests/mermaiden/test_mermaid_preview.py +14 -0
  347. mermaiden-3.0.0/tests/mermaiden/test_rendered_diagrams.py +235 -0
  348. mermaiden-3.0.0/tests/mermaiden/test_treeview.py +12 -0
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ .ruff_cache/
4
+ __pycache__/
5
+ *.py[cod]
6
+ src/mermaiden/_version.py
7
+ dist/
8
+ .compatibility-artifacts/
9
+ .preview/
10
+ compatibility/toolchains/*/node_modules/
11
+ .dev/
@@ -0,0 +1 @@
1
+ 24.17.0
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: mermaiden
3
+ Version: 3.0.0
4
+ Summary: Typed deterministic Mermaid source generation for Python.
5
+ Project-URL: Repository, https://github.com/szpak-dev/mermaiden
6
+ Project-URL: Issues, https://github.com/szpak-dev/mermaiden/issues
7
+ Author: 9orky
8
+ License-Expression: MIT
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: jinja2>=3.1
17
+ Requires-Dist: pydantic>=2.12
18
+ Requires-Dist: wireup>=2.12.0
19
+ Provides-Extra: dev
20
+ Requires-Dist: build>=1.3; extra == 'dev'
21
+ Requires-Dist: import-linter>=2.11; extra == 'dev'
22
+ Requires-Dist: jsonschema>=4.25; extra == 'dev'
23
+ Requires-Dist: packaging>=25; extra == 'dev'
24
+ Requires-Dist: pyright>=1.1.403; extra == 'dev'
25
+ Requires-Dist: pytest>=9; extra == 'dev'
26
+ Requires-Dist: pyyaml>=6; extra == 'dev'
27
+ Requires-Dist: ruff>=0.14; extra == 'dev'
28
+ Requires-Dist: twine>=6; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # mermaiden
32
+
33
+ `mermaiden` generates deterministic Mermaid source from typed Python diagram models. It supports the Mermaid syntax families registered by the package and validates each diagram before rendering its text.
34
+
35
+ The package produces Mermaid text only. Render it with Mermaid in a browser, Markdown viewer, or your own CLI workflow.
36
+
37
+ ## Installation
38
+
39
+ Python 3.12 or later is required.
40
+
41
+ ```sh
42
+ pip install mermaiden
43
+ ```
44
+
45
+ ## Quick start
46
+
47
+ ```python
48
+ from mermaiden.application import Application
49
+
50
+ application = Application.create()
51
+ source = application.rendered_diagrams()["flowchart"]
52
+ print(source)
53
+ ```
54
+
55
+ `Application.available_diagrams()` returns the supported diagram catalog. `Application.diagram_info(diagram_id)` returns the typed diagram API for an individual syntax.
56
+
57
+ ## Development
58
+
59
+ The repository uses a single host-mode CI target:
60
+
61
+ ```sh
62
+ make ci
63
+ ```
64
+
65
+ It installs the development dependencies, runs linting, type checks, tests, compatibility validation, Mermaid CLI rendering, and wheel validation. To open the locally generated diagram preview, run:
66
+
67
+ ```sh
68
+ make diagrams-test
69
+ ```
70
+
71
+ ## Release
72
+
73
+ Releases are versioned by annotated `vX.Y.Z` tags. After `make ci` passes, create and push the tag, then publish the GitHub release:
74
+
75
+ ```sh
76
+ git tag -a v2.0.0 -m "v2.0.0"
77
+ git push origin v2.0.0
78
+ gh release create v2.0.0 --verify-tag --generate-notes --title v2.0.0
79
+ ```
@@ -0,0 +1,49 @@
1
+ # mermaiden
2
+
3
+ `mermaiden` generates deterministic Mermaid source from typed Python diagram models. It supports the Mermaid syntax families registered by the package and validates each diagram before rendering its text.
4
+
5
+ The package produces Mermaid text only. Render it with Mermaid in a browser, Markdown viewer, or your own CLI workflow.
6
+
7
+ ## Installation
8
+
9
+ Python 3.12 or later is required.
10
+
11
+ ```sh
12
+ pip install mermaiden
13
+ ```
14
+
15
+ ## Quick start
16
+
17
+ ```python
18
+ from mermaiden.application import Application
19
+
20
+ application = Application.create()
21
+ source = application.rendered_diagrams()["flowchart"]
22
+ print(source)
23
+ ```
24
+
25
+ `Application.available_diagrams()` returns the supported diagram catalog. `Application.diagram_info(diagram_id)` returns the typed diagram API for an individual syntax.
26
+
27
+ ## Development
28
+
29
+ The repository uses a single host-mode CI target:
30
+
31
+ ```sh
32
+ make ci
33
+ ```
34
+
35
+ It installs the development dependencies, runs linting, type checks, tests, compatibility validation, Mermaid CLI rendering, and wheel validation. To open the locally generated diagram preview, run:
36
+
37
+ ```sh
38
+ make diagrams-test
39
+ ```
40
+
41
+ ## Release
42
+
43
+ Releases are versioned by annotated `vX.Y.Z` tags. After `make ci` passes, create and push the tag, then publish the GitHub release:
44
+
45
+ ```sh
46
+ git tag -a v2.0.0 -m "v2.0.0"
47
+ git push origin v2.0.0
48
+ gh release create v2.0.0 --verify-tag --generate-notes --title v2.0.0
49
+ ```
@@ -0,0 +1,70 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.28", "hatch-vcs>=0.5"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mermaiden"
7
+ dynamic = ["version"]
8
+ description = "Typed deterministic Mermaid source generation for Python."
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = "MIT"
12
+ authors = [{ name = "9orky" }]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Typing :: Typed",
20
+ ]
21
+
22
+ dependencies = [
23
+ "jinja2>=3.1",
24
+ "pydantic>=2.12",
25
+ "wireup>=2.12.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = ["build>=1.3", "import-linter>=2.11", "jsonschema>=4.25", "packaging>=25", "pyright>=1.1.403", "pytest>=9", "pyyaml>=6", "ruff>=0.14", "twine>=6"]
30
+
31
+ [dependency-groups]
32
+ dev = ["build>=1.3", "import-linter>=2.11", "jsonschema>=4.25", "packaging>=25", "pyright>=1.1.403", "pytest>=9", "pyyaml>=6", "ruff>=0.14", "twine>=6"]
33
+
34
+ [project.urls]
35
+ Repository = "https://github.com/szpak-dev/mermaiden"
36
+ Issues = "https://github.com/szpak-dev/mermaiden/issues"
37
+
38
+ [tool.hatch.version]
39
+ source = "vcs"
40
+ tag-pattern = '^v(?P<version>\d+\.\d+\.\d+)$'
41
+ fallback-version = "0.0.0"
42
+
43
+ [tool.hatch.build.hooks.vcs]
44
+ version-file = "src/mermaiden/_version.py"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/mermaiden"]
48
+
49
+ [tool.hatch.build.targets.sdist]
50
+ include = ["compatibility", "docs", "examples", "scripts", "src", "tests", ".node-version", "README.md", "pyproject.toml"]
51
+
52
+ [tool.pytest.ini_options]
53
+ testpaths = ["tests"]
54
+ addopts = ["-ra", "--strict-config", "--strict-markers"]
55
+ filterwarnings = ["error"]
56
+
57
+ [tool.ruff]
58
+ line-length = 120
59
+ extend-exclude = ["**/_version.py"]
60
+ target-version = "py312"
61
+
62
+ [tool.ruff.lint]
63
+ select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
64
+
65
+ [tool.pyright]
66
+ include = ["src", "tests"]
67
+ pythonVersion = "3.12"
68
+ typeCheckingMode = "strict"
69
+ venvPath = "."
70
+ venv = ".venv"
@@ -0,0 +1,56 @@
1
+ # Diagram core prototype
2
+
3
+ The model has five concepts:
4
+
5
+ - **Diagram** owns its state and is the Visitor host.
6
+ - **Element** is either an entity or a recursively nested container.
7
+ - **Relation** binds IDs of existing elements.
8
+ - **Constraint** is a side-effect-free Visitor producing structured violations.
9
+ - **Annotation** adds data through typed references to elements or relations.
10
+
11
+ Dependency direction is `flowchart/treeview -> runtime -> core`. Core is independent of
12
+ Wireup and Mermaid. Runtime is a service-oriented building environment: frozen
13
+ dataclass services receive dependencies through typed fields, while scoped
14
+ `DiagramState` owns committed and staged state. No service has a handwritten
15
+ constructor.
16
+
17
+ Every mutation is executed by a Unit of Work. An Observer evaluates constraints
18
+ before and after staging the candidate. Blocking violations roll the candidate
19
+ back atomically; advisory violations allow deliberately incomplete diagrams to
20
+ be built and repaired incrementally.
21
+
22
+ Flowchart and Tree View are separate aggregates resolved from the composition root. Flowchart's API
23
+ uses domain operations such as `add_start`, `add_decision`, `add_flow`, and
24
+ `remove_flow`. Callers pass primitive arguments; the aggregate creates its
25
+ `FlowNode`, `Flow`, and `Note` values internally. Generic `Diagram` operations
26
+ are mapped to the same flowchart vocabulary and the same constraint pipeline,
27
+ so they cannot bypass domain rules.
28
+
29
+ The principal patterns are:
30
+
31
+ - **Aggregate** for state ownership and behavior boundaries,
32
+ - **Composite** for recursive element containment,
33
+ - **Visitor** for structural and diagram-specific constraints,
34
+ - **Observer** for before/after constraint evaluation,
35
+ - **Unit of Work / Memento** for stage, commit, and rollback,
36
+ - **Strategy** through the injected change and inspection contracts.
37
+
38
+ Rendering implementations remain outside core. A renderer consumes the
39
+ read-only `DiagramView` contract through `root_elements`, `walk_elements`,
40
+ `find_relations`, and `find_annotations`, without access to runtime state or
41
+ mutation services. The generic `Renderer` strategy does not prescribe a
42
+ technology or output type.
43
+
44
+ The generic `rendering` adapter package provides strict Jinja-to-text rendering
45
+ and canonical LF-only output. It contains no Mermaid syntax and can be reused by
46
+ diagram-specific rendering packages.
47
+
48
+ The accepted initial flowchart surface is documented in
49
+ [`diagrams/flowchart/VOCABULARY.md`](diagrams/flowchart/VOCABULARY.md).
50
+
51
+ Each diagram rendering package emits deterministic Mermaid body text through Jinja
52
+ snippets. Each semantic element, relation, and annotation owns its Mermaid
53
+ representation in a template; renderer Python code only configures safe syntax
54
+ filters and invokes the root template. The composition root exposes one
55
+ `MermaidRenderer`, which dispatches every supported diagram and applies the
56
+ same default Mermaid `wrap: true` document configuration.
File without changes
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '3.0.0'
22
+ __version_tuple__ = version_tuple = (3, 0, 0)
23
+
24
+ __commit_id__ = commit_id = None
@@ -0,0 +1,98 @@
1
+ import argparse
2
+ from dataclasses import dataclass
3
+ from pathlib import Path
4
+
5
+ from wireup import SyncContainer, create_sync_container
6
+
7
+ import mermaiden
8
+
9
+ from .diagrams.registry import DiagramInfo, DiagramRegistry
10
+ from .mermaid.compatibility import CompatibilityReport, MermaidCompatibility
11
+ from .mermaid.compatibility.schema import MermaidDiagramConfig, MermaidSchemaStore
12
+ from .mermaid.fixtures import DiagramFixtures
13
+ from .mermaid.preview import MermaidPreview
14
+
15
+
16
+ @dataclass(frozen=True, slots=True)
17
+ class Application:
18
+ container: SyncContainer
19
+
20
+ @classmethod
21
+ def create(cls) -> "Application":
22
+ return cls(create_sync_container(injectables=[mermaiden], config={}))
23
+
24
+ def available_diagrams(self) -> tuple[DiagramInfo, ...]:
25
+ with self.container.enter_scope() as scope:
26
+ return scope.get(DiagramRegistry).available()
27
+
28
+ def diagram_info(self, diagram_id: str) -> DiagramInfo:
29
+ with self.container.enter_scope() as scope:
30
+ return scope.get(DiagramRegistry).get(diagram_id)
31
+
32
+ def diagram_info_for_config(self, config_key: str) -> DiagramInfo:
33
+ with self.container.enter_scope() as scope:
34
+ return scope.get(DiagramRegistry).get_by_config_key(config_key)
35
+
36
+ def mermaid_diagram_configs(self) -> tuple[MermaidDiagramConfig, ...]:
37
+ with self.container.enter_scope() as scope:
38
+ return scope.get(MermaidSchemaStore).diagram_configs()
39
+
40
+ def rendered_diagrams(self) -> dict[str, str]:
41
+ with self.container.enter_scope() as scope:
42
+ return scope.get(DiagramFixtures).render()
43
+
44
+ def write_fixtures(self, output: Path) -> tuple[Path, ...]:
45
+ output.mkdir(parents=True, exist_ok=True)
46
+ return tuple(
47
+ self._write_source(output, name, source) for name, source in self.rendered_diagrams().items()
48
+ )
49
+
50
+ def write_preview(self, output: Path) -> Path:
51
+ with self.container.enter_scope() as scope:
52
+ preview = scope.get(MermaidPreview)
53
+ return preview.write_sources(self.rendered_diagrams(), output)
54
+
55
+ def compatibility_report(self) -> CompatibilityReport:
56
+ with self.container.enter_scope() as scope:
57
+ return scope.get(MermaidCompatibility).inspect()
58
+
59
+ def verify_compatibility(self) -> CompatibilityReport:
60
+ with self.container.enter_scope() as scope:
61
+ return scope.get(MermaidCompatibility).verify()
62
+
63
+ @staticmethod
64
+ def _write_source(output: Path, name: str, source: str) -> Path:
65
+ path = output / f"{name}.mmd"
66
+ path.write_text(source, encoding="utf-8")
67
+ return path
68
+
69
+ @classmethod
70
+ def run(cls) -> None:
71
+ parser = argparse.ArgumentParser()
72
+ commands = parser.add_subparsers(dest="command", required=True)
73
+ fixtures = commands.add_parser("fixtures")
74
+ fixtures.add_argument("--output", "-o", type=Path, default=Path(".preview"))
75
+ preview = commands.add_parser("preview")
76
+ preview.add_argument("--output", "-o", type=Path, default=Path(".preview/index.html"))
77
+ commands.add_parser("compat")
78
+ arguments = parser.parse_args()
79
+ application = cls.create()
80
+ if arguments.command == "fixtures":
81
+ for path in application.write_fixtures(arguments.output):
82
+ print(path)
83
+ if arguments.command == "preview":
84
+ print(application.write_preview(arguments.output))
85
+ if arguments.command == "compat":
86
+ report = application.verify_compatibility()
87
+ for diagram in report.diagrams:
88
+ print(f"{diagram.diagram_id}: {'valid' if report.diagram_valid(diagram) else 'invalid'}")
89
+ for diagram in report.missing_diagrams:
90
+ print(f"{diagram.config_key}: not implemented ({diagram.schema_definition})")
91
+ for violation in report.syntax_violations:
92
+ print(f"{violation.diagram_id}: {violation.message}")
93
+ if not report.valid:
94
+ raise SystemExit(1)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ Application.run()
@@ -0,0 +1,34 @@
1
+ from .annotation import Annotation, DataAnnotation, TargetKind, TargetRef
2
+ from .constraint import (
3
+ ChangeRejected,
4
+ ChangeReport,
5
+ Constraint,
6
+ ConstraintLevel,
7
+ ValidationReport,
8
+ Violation,
9
+ )
10
+ from .diagram import Diagram, DiagramView, DiagramVisitor
11
+ from .element import Container, Element, Entity
12
+ from .error import OperationError
13
+ from .relation import Relation
14
+
15
+ __all__ = [
16
+ "Annotation",
17
+ "ChangeRejected",
18
+ "ChangeReport",
19
+ "Constraint",
20
+ "ConstraintLevel",
21
+ "Container",
22
+ "DataAnnotation",
23
+ "Diagram",
24
+ "DiagramView",
25
+ "DiagramVisitor",
26
+ "Element",
27
+ "Entity",
28
+ "OperationError",
29
+ "Relation",
30
+ "TargetKind",
31
+ "TargetRef",
32
+ "ValidationReport",
33
+ "Violation",
34
+ ]
@@ -0,0 +1,25 @@
1
+ from collections.abc import Mapping
2
+ from dataclasses import dataclass
3
+ from enum import StrEnum
4
+
5
+
6
+ class TargetKind(StrEnum):
7
+ ELEMENT = "element"
8
+ RELATION = "relation"
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class TargetRef:
13
+ kind: TargetKind
14
+ id: str
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class Annotation:
19
+ id: str
20
+ targets: tuple[TargetRef, ...]
21
+
22
+
23
+ @dataclass(frozen=True, slots=True)
24
+ class DataAnnotation(Annotation):
25
+ data: Mapping[str, object]
@@ -0,0 +1,109 @@
1
+ from abc import ABC, abstractmethod
2
+ from collections.abc import Sequence
3
+ from dataclasses import dataclass
4
+ from enum import StrEnum
5
+ from typing import Protocol
6
+
7
+ from .annotation import Annotation
8
+ from .element import Element
9
+ from .relation import Relation
10
+
11
+
12
+ class ConstraintLevel(StrEnum):
13
+ BLOCKING = "blocking"
14
+ ADVISORY = "advisory"
15
+
16
+
17
+ class ConstraintDiagram(Protocol):
18
+ @property
19
+ def root_elements(self) -> Sequence[Element]: ...
20
+
21
+ def walk_elements(self, parent_id: str = "") -> Sequence[Element]: ...
22
+
23
+ def find_relations(self, element_id: str = "") -> Sequence[Relation]: ...
24
+
25
+ def find_annotations(self, target_id: str = "") -> Sequence[Annotation]: ...
26
+
27
+
28
+ @dataclass(frozen=True, slots=True)
29
+ class Violation:
30
+ code: str
31
+ message: str
32
+ path: str = ""
33
+ level: ConstraintLevel = ConstraintLevel.ADVISORY
34
+
35
+
36
+ @dataclass(frozen=True, slots=True)
37
+ class ValidationReport:
38
+ violations: tuple[Violation, ...] = ()
39
+
40
+ @property
41
+ def blocking(self) -> tuple[Violation, ...]:
42
+ return tuple(item for item in self.violations if item.level is ConstraintLevel.BLOCKING)
43
+
44
+ @property
45
+ def advisory(self) -> tuple[Violation, ...]:
46
+ return tuple(item for item in self.violations if item.level is ConstraintLevel.ADVISORY)
47
+
48
+ @property
49
+ def can_commit(self) -> bool:
50
+ return not self.blocking
51
+
52
+ @property
53
+ def is_valid(self) -> bool:
54
+ return not self.violations
55
+
56
+ def __bool__(self) -> bool:
57
+ return self.can_commit
58
+
59
+
60
+ @dataclass(frozen=True, slots=True)
61
+ class ChangeReport:
62
+ operation: str
63
+ before: ValidationReport
64
+ after: ValidationReport
65
+ accepted: bool
66
+
67
+ @property
68
+ def introduced(self) -> tuple[Violation, ...]:
69
+ return tuple(item for item in self.after.violations if item not in self.before.violations)
70
+
71
+ @property
72
+ def resolved(self) -> tuple[Violation, ...]:
73
+ return tuple(item for item in self.before.violations if item not in self.after.violations)
74
+
75
+ @property
76
+ def current(self) -> ValidationReport:
77
+ return self.after if self.accepted else self.before
78
+
79
+
80
+ @dataclass(frozen=True, slots=True)
81
+ class ChangeRejected(RuntimeError):
82
+ operation: str
83
+ report: ValidationReport
84
+
85
+ def __str__(self) -> str:
86
+ details = "; ".join(item.message for item in self.report.blocking)
87
+ return f"Cannot {self.operation}: {details or 'the operation was rejected.'}"
88
+
89
+
90
+ class Constraint(ABC):
91
+ @property
92
+ @abstractmethod
93
+ def code(self) -> str: ...
94
+
95
+ @property
96
+ def level(self) -> ConstraintLevel:
97
+ return ConstraintLevel.ADVISORY
98
+
99
+ @abstractmethod
100
+ def visit(self, diagram: ConstraintDiagram) -> tuple[Violation, ...]: ...
101
+
102
+ def violation(self, message: str, *, path: str = "") -> Violation:
103
+ return Violation(code=self.code, message=message, path=path, level=self.level)
104
+
105
+
106
+ class BlockingConstraint(Constraint):
107
+ @property
108
+ def level(self) -> ConstraintLevel:
109
+ return ConstraintLevel.BLOCKING
@@ -0,0 +1,68 @@
1
+ from abc import ABC, abstractmethod
2
+ from collections.abc import Mapping, Sequence
3
+ from typing import Protocol, TypeVar
4
+
5
+ from .annotation import Annotation
6
+ from .constraint import ChangeReport, ValidationReport
7
+ from .element import Container, Element, Entity
8
+ from .relation import Relation
9
+
10
+ Result = TypeVar("Result", covariant=True)
11
+
12
+
13
+ class DiagramVisitor(Protocol[Result]):
14
+ def visit(self, diagram: "Diagram") -> Result: ...
15
+
16
+
17
+ class DiagramView(ABC):
18
+ @property
19
+ @abstractmethod
20
+ def kind(self) -> str: ...
21
+
22
+ @property
23
+ @abstractmethod
24
+ def mermaid_configuration(self) -> Mapping[str, object]: ...
25
+
26
+ @property
27
+ @abstractmethod
28
+ def root_elements(self) -> Sequence[Element]: ...
29
+
30
+ @abstractmethod
31
+ def find_element(self, id: str) -> Element | None: ...
32
+
33
+ @abstractmethod
34
+ def walk_elements(self, parent_id: str = "") -> Sequence[Element]: ...
35
+
36
+ @abstractmethod
37
+ def find_relations(self, element_id: str = "") -> Sequence[Relation]: ...
38
+
39
+ @abstractmethod
40
+ def find_annotations(self, target_id: str = "") -> Sequence[Annotation]: ...
41
+
42
+ @abstractmethod
43
+ def validate(self) -> ValidationReport: ...
44
+
45
+
46
+ class Diagram(DiagramView):
47
+ @abstractmethod
48
+ def remove_element(self, id: str, *, cascade: bool = False) -> ChangeReport: ...
49
+
50
+ @abstractmethod
51
+ def remove_relation(self, id: str) -> ChangeReport: ...
52
+
53
+ @abstractmethod
54
+ def remove_annotation(self, id: str) -> ChangeReport: ...
55
+
56
+ def accept(self, visitor: DiagramVisitor[Result]) -> Result:
57
+ return visitor.visit(self)
58
+
59
+
60
+ __all__ = [
61
+ "Container",
62
+ "Diagram",
63
+ "DiagramView",
64
+ "DiagramVisitor",
65
+ "Element",
66
+ "Entity",
67
+ "Relation",
68
+ ]
@@ -0,0 +1,18 @@
1
+ from abc import ABC
2
+ from dataclasses import dataclass
3
+
4
+
5
+ @dataclass(frozen=True, slots=True)
6
+ class Element(ABC):
7
+ id: str
8
+ label: str
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class Entity(Element):
13
+ pass
14
+
15
+
16
+ @dataclass(frozen=True, slots=True)
17
+ class Container(Element):
18
+ elements: tuple[Element, ...] = ()
@@ -0,0 +1,2 @@
1
+ class OperationError(Exception):
2
+ pass
@@ -0,0 +1,8 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True, slots=True)
5
+ class Relation:
6
+ id: str
7
+ element_ids: tuple[str, ...]
8
+ label: str = ""
File without changes