zombie-mermaid 4.2.1 → 4.2.3

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 (91) hide show
  1. package/package.json +9 -7
  2. package/src/__tests__/architecture-integration.test.ts +0 -217
  3. package/src/__tests__/ascii-ansi.test.ts +0 -539
  4. package/src/__tests__/ascii-draw-bundles.test.ts +0 -849
  5. package/src/__tests__/ascii-edge-bundling-routing.test.ts +0 -214
  6. package/src/__tests__/ascii-edge-cross-style-overlap.test.ts +0 -216
  7. package/src/__tests__/ascii-grid-deep-chain.test.ts +0 -64
  8. package/src/__tests__/ascii-hyperlinks.test.ts +0 -364
  9. package/src/__tests__/ascii-nested-subgraph-sibling-order-444.test.ts +0 -108
  10. package/src/__tests__/ascii-nonmember-beside-frame-1283.test.ts +0 -113
  11. package/src/__tests__/ascii-package-boundary.test.ts +0 -291
  12. package/src/__tests__/ascii-parallel-edges-329.test.ts +0 -315
  13. package/src/__tests__/ascii-parallel-lane-border-1230.test.ts +0 -71
  14. package/src/__tests__/ascii-reverse-direction-edges-629.test.ts +0 -282
  15. package/src/__tests__/ascii-stacked-frame-geometry-1285.test.ts +0 -107
  16. package/src/__tests__/ascii-subgraph-bbox.test.ts +0 -139
  17. package/src/__tests__/ascii-subgraph-later-edgeless-301.test.ts +0 -277
  18. package/src/__tests__/browser.test.ts +0 -34
  19. package/src/__tests__/c4-integration.test.ts +0 -161
  20. package/src/__tests__/c4-orientation.test.ts +0 -162
  21. package/src/__tests__/c4-upstream-integration.test.ts +0 -211
  22. package/src/__tests__/class-click-interactions.test.ts +0 -232
  23. package/src/__tests__/class-integration.test.ts +0 -154
  24. package/src/__tests__/class-notes.test.ts +0 -317
  25. package/src/__tests__/class-parser-error-messages.test.ts +0 -162
  26. package/src/__tests__/class-parser.test.ts +0 -347
  27. package/src/__tests__/class-styling.test.ts +0 -485
  28. package/src/__tests__/cli-diagrams.test.ts +0 -106
  29. package/src/__tests__/cli-e2e.test.ts +0 -275
  30. package/src/__tests__/cli-entrypoint.test.ts +0 -146
  31. package/src/__tests__/cli-mcp-dispatch.test.ts +0 -68
  32. package/src/__tests__/cli-mcp.test.ts +0 -44
  33. package/src/__tests__/cli-png.test.ts +0 -35
  34. package/src/__tests__/cli-render.test.ts +0 -988
  35. package/src/__tests__/cli-test-helpers.ts +0 -54
  36. package/src/__tests__/cli-web-dispatch.test.ts +0 -62
  37. package/src/__tests__/cli-web.test.ts +0 -203
  38. package/src/__tests__/cli.test.ts +0 -1027
  39. package/src/__tests__/compound-flat-layout.test.ts +0 -901
  40. package/src/__tests__/direction-override.test.ts +0 -397
  41. package/src/__tests__/edge-approach-direction.test.ts +0 -295
  42. package/src/__tests__/edge-bundling-node-clearance.test.ts +0 -179
  43. package/src/__tests__/elk-layout-cache.test.ts +0 -223
  44. package/src/__tests__/er-click-unsupported.test.ts +0 -69
  45. package/src/__tests__/er-integration.test.ts +0 -531
  46. package/src/__tests__/er-parser-error-messages.test.ts +0 -82
  47. package/src/__tests__/er-parser.test.ts +0 -294
  48. package/src/__tests__/expanded-shapes.test.ts +0 -229
  49. package/src/__tests__/flowchart-back-edge-prereversal-1239.test.ts +0 -212
  50. package/src/__tests__/flowchart-syntax-gaps.test.ts +0 -371
  51. package/src/__tests__/guides-examples.test.ts +0 -181
  52. package/src/__tests__/integration.test.ts +0 -729
  53. package/src/__tests__/interactivity-config.test.ts +0 -723
  54. package/src/__tests__/interactivity-option.test.ts +0 -173
  55. package/src/__tests__/layout-disconnected.test.ts +0 -384
  56. package/src/__tests__/layout-engine.test.ts +0 -91
  57. package/src/__tests__/linkstyle.test.ts +0 -133
  58. package/src/__tests__/mcp-render-ascii-tool.test.ts +0 -95
  59. package/src/__tests__/mcp-render-svg-theme-guard.test.ts +0 -36
  60. package/src/__tests__/mcp-render-svg-tool.test.ts +0 -118
  61. package/src/__tests__/mermaid-entity-codes.test.ts +0 -114
  62. package/src/__tests__/monospace-metrics.test.ts +0 -74
  63. package/src/__tests__/multiline-labels.test.ts +0 -924
  64. package/src/__tests__/nested-subgraph-direction-crossing.test.ts +0 -322
  65. package/src/__tests__/nested-subgraph-edge-container-offset.test.ts +0 -151
  66. package/src/__tests__/package-info.test.ts +0 -51
  67. package/src/__tests__/parser.test.ts +0 -1544
  68. package/src/__tests__/render-options-overrides.test.ts +0 -257
  69. package/src/__tests__/render-options-per-type.test.ts +0 -178
  70. package/src/__tests__/renderer.test.ts +0 -743
  71. package/src/__tests__/resolve-colors.test.ts +0 -448
  72. package/src/__tests__/self-loop-edges.test.ts +0 -112
  73. package/src/__tests__/sequence-activation-check.test.ts +0 -219
  74. package/src/__tests__/sequence-integration.test.ts +0 -312
  75. package/src/__tests__/sequence-layout.test.ts +0 -1103
  76. package/src/__tests__/sequence-parser-syntax-errors.test.ts +0 -179
  77. package/src/__tests__/sequence-parser.test.ts +0 -821
  78. package/src/__tests__/state-composite-order-1287.test.ts +0 -132
  79. package/src/__tests__/state-flow-order-1240.test.ts +0 -113
  80. package/src/__tests__/state-styling.test.ts +0 -150
  81. package/src/__tests__/statements.test.ts +0 -264
  82. package/src/__tests__/styles.test.ts +0 -220
  83. package/src/__tests__/subgraph-title-edge-gap-1239.test.ts +0 -238
  84. package/src/__tests__/svg-accessible-name-conformance.test.ts +0 -276
  85. package/src/__tests__/svg-accessible-name.test.ts +0 -421
  86. package/src/__tests__/svg-csp-style-options.test.ts +0 -427
  87. package/src/__tests__/workspace-package-boundaries.test.ts +0 -336
  88. package/src/__tests__/xychart-integration.test.ts +0 -137
  89. package/src/__tests__/xychart-layout.test.ts +0 -205
  90. package/src/__tests__/xychart-parser-categories.test.ts +0 -78
  91. package/src/__tests__/xychart-parser-errors.test.ts +0 -95
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zombie-mermaid",
3
- "version": "4.2.1",
3
+ "version": "4.2.3",
4
4
  "license": "MIT",
5
5
  "description": "Render Mermaid diagrams as beautiful SVGs or ASCII art. Ultra-fast, fully themeable, zero DOM dependencies. Maintained fork of beautiful-mermaid.",
6
6
  "type": "module",
@@ -79,6 +79,7 @@
79
79
  },
80
80
  "files": [
81
81
  "src/",
82
+ "!src/**/__tests__",
82
83
  "dist/",
83
84
  "LICENSE",
84
85
  "README.md"
@@ -90,11 +91,11 @@
90
91
  "@modelcontextprotocol/sdk": "^1.30.0",
91
92
  "elkjs": "^0.11.0",
92
93
  "entities": "^7.0.1",
93
- "@zombie-mermaid/ascii-renderer": "4.2.1",
94
- "@zombie-mermaid/core": "4.2.1",
95
- "@zombie-mermaid/mcp": "4.2.1",
96
- "@zombie-mermaid/mermaid-parser": "4.2.1",
97
- "@zombie-mermaid/svg-renderer": "4.2.1"
94
+ "@zombie-mermaid/ascii-renderer": "4.2.3",
95
+ "@zombie-mermaid/mcp": "4.2.3",
96
+ "@zombie-mermaid/svg-renderer": "4.2.3",
97
+ "@zombie-mermaid/mermaid-parser": "4.2.3",
98
+ "@zombie-mermaid/core": "4.2.3"
98
99
  },
99
100
  "devDependencies": {
100
101
  "@changesets/changelog-github": "^1.0.0",
@@ -181,6 +182,7 @@
181
182
  "dashboard:data": "tsx scripts/generate-dashboard-data.ts",
182
183
  "upstream:pr-candidates": "tsx scripts/list-upstream-pr-rescue-candidates.ts",
183
184
  "audit:responsive": "tsx scripts/audit-responsive.ts",
184
- "layout:oracle": "tsx scripts/layout-oracle.ts"
185
+ "layout:oracle": "tsx scripts/layout-oracle.ts",
186
+ "label:oracle": "tsx scripts/label-position-oracle.ts"
185
187
  }
186
188
  }
@@ -1,217 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { splitStatements, detectDiagramType } from '@zombie-mermaid/core'
3
- import {
4
- parseArchitecture,
5
- architectureToGraph,
6
- } from '@zombie-mermaid/mermaid-parser'
7
- import { renderMermaidSVG, renderMermaidASCII } from '../index.ts'
8
-
9
- const parse = (src: string) => parseArchitecture(splitStatements(src))
10
- const lower = (src: string) => architectureToGraph(parse(src))
11
-
12
- const DOC = `architecture-beta
13
- group api(cloud)[API]
14
- group edge(internet)[Edge] in api
15
- service db(database)[Database] in api
16
- service server(server)[Server] in api
17
- service gw[Gateway] in edge
18
- junction j in api
19
- service client(internet)[Client]
20
- db:L -- R:server
21
- server:T <--> B:j
22
- gw{group}:R --> L:client
23
- align row db server`
24
-
25
- describe('architecture-beta parsing', () => {
26
- it('detects both header spellings', () => {
27
- expect(detectDiagramType('architecture-beta\nservice a')).toBe(
28
- 'architecture',
29
- )
30
- expect(detectDiagramType('architecture\nservice a')).toBe('architecture')
31
- })
32
-
33
- it('parses groups, nesting, services, junctions and edges', () => {
34
- const d = parse(DOC)
35
- expect(d.groups.map((g) => [g.id, g.title, g.parent])).toEqual([
36
- ['api', 'API', undefined],
37
- ['edge', 'Edge', 'api'],
38
- ])
39
- expect(d.services.find((s) => s.id === 'db')).toMatchObject({
40
- icon: 'database',
41
- title: 'Database',
42
- parent: 'api',
43
- })
44
- expect(d.services.find((s) => s.id === 'gw')?.icon).toBeUndefined()
45
- expect(d.junctions).toEqual([{ id: 'j', parent: 'api' }])
46
- expect(d.edges).toHaveLength(3)
47
- expect(d.edges[1]).toMatchObject({ arrowStart: true, arrowEnd: true })
48
- expect(d.edges[2]).toMatchObject({ sourceGroup: true, arrowEnd: true })
49
- })
50
-
51
- it('titles default to the id', () => {
52
- expect(parse('architecture-beta\nservice a').services[0]?.title).toBe('a')
53
- })
54
-
55
- it.each([
56
- ['service a\nservice a', /line 3.*duplicate id "a"/s],
57
- ['service a in nope', /line 2.*must name a declared group/s],
58
- ['group g in g', /line 2.*inside itself/s],
59
- ['group a in b\ngroup b in a', /nested inside itself/],
60
- ['service a\na:R -- L:zzz', /line 3.*unknown id "zzz"/s],
61
- ['group g\nservice a\na:R -- L:g', /line 4.*not the group/s],
62
- ['service a\nservice b\na{group}:R -- L:b', /needs "a" to be declared/],
63
- ['service a\nbogus line', /line 3.*unrecognized/s],
64
- ])('rejects %j', (body, message) => {
65
- expect(() => parse(`architecture-beta\n${body}`)).toThrow(message)
66
- })
67
- })
68
-
69
- describe('architecture-beta lowering', () => {
70
- it('maps groups to nested subgraphs and icons to shapes', () => {
71
- const g = lower(DOC)
72
- expect(g.subgraphs).toHaveLength(1)
73
- const api = g.subgraphs[0]!
74
- expect(api.id).toBe('api')
75
- expect(api.nodeIds).toEqual(['db', 'server', 'j'])
76
- expect(api.children.map((c) => [c.id, c.nodeIds])).toEqual([
77
- ['edge', ['gw']],
78
- ])
79
- expect(g.nodes.get('db')?.shape).toBe('cylinder')
80
- expect(g.nodes.get('server')?.shape).toBe('rectangle')
81
- expect(g.nodes.get('j')).toMatchObject({
82
- shape: 'filled-circle',
83
- label: '',
84
- })
85
- })
86
-
87
- it('attaches {group} ends to the enclosing group', () => {
88
- const e = lower(DOC).edges[2]!
89
- expect(e).toMatchObject({ source: 'edge', target: 'client' })
90
- })
91
-
92
- it('picks the flow axis from the ports', () => {
93
- expect(
94
- lower('architecture-beta\nservice a\nservice b\na:R -- L:b').direction,
95
- ).toBe('LR')
96
- expect(
97
- lower('architecture-beta\nservice a\nservice b\na:B -- T:b').direction,
98
- ).toBe('TB')
99
- })
100
-
101
- it('reverses edges that run against the flow, keeping arrowheads on the true ends', () => {
102
- // `a:L --> R:b` puts a to the right of b, arrow pointing at b.
103
- const [e] = lower(
104
- 'architecture-beta\nservice a\nservice b\na:L --> R:b\n',
105
- ).edges
106
- expect(e).toMatchObject({
107
- source: 'b',
108
- target: 'a',
109
- hasArrowStart: true,
110
- hasArrowEnd: false,
111
- })
112
- })
113
- })
114
-
115
- describe('architecture-beta rendering', () => {
116
- it('renders SVG with group titles and service labels', () => {
117
- const svg = renderMermaidSVG(DOC)
118
- for (const label of [
119
- 'API',
120
- 'Edge',
121
- 'Database',
122
- 'Server',
123
- 'Gateway',
124
- 'Client',
125
- ]) {
126
- expect(svg).toContain(label)
127
- }
128
- })
129
-
130
- it('renders ASCII', () => {
131
- const out = renderMermaidASCII(
132
- 'architecture-beta\n service a[Alpha]\n service b[Beta]\n a:R --> L:b',
133
- )
134
- expect(out).toContain('Alpha')
135
- expect(out).toContain('Beta')
136
- })
137
- })
138
-
139
- const NESTED = `architecture-beta
140
- group api(cloud)[API]
141
- group inner(cloud)[Inner] in api
142
- service a[Alpha] in inner
143
- service b[Beta] in api
144
- junction j in api
145
- a:R -- L:j
146
- j:R --> L:b`
147
-
148
- describe('architecture-beta nested groups and junctions', () => {
149
- it('SVG draws nested groups and a junction dot', () => {
150
- const svg = renderMermaidSVG(NESTED)
151
- expect(svg).toContain('data-id="api" data-label="API"')
152
- expect(svg).toContain('data-id="inner" data-label="Inner"')
153
- expect(svg).toContain(
154
- 'data-id="j" data-label="" data-shape="filled-circle"',
155
- )
156
- expect(svg.match(/class="subgraph"/g)).toHaveLength(2)
157
- expect(svg.match(/class="edge"/g)).toHaveLength(2)
158
- // The inner group is drawn after (on top of) its parent.
159
- expect(svg.indexOf('data-id="api"')).toBeLessThan(
160
- svg.indexOf('data-id="inner"'),
161
- )
162
- })
163
-
164
- it('ASCII draws the inner group inside the outer one', () => {
165
- const lines = renderMermaidASCII(NESTED).split('\n')
166
- const find = (s: string) => lines.find((l) => l.includes(s))!
167
- // The outer border encloses the inner box: both its left and right
168
- // borders flank the inner group's own title row.
169
- expect(find('API')).toMatch(/^│\s+API\s+│$/)
170
- expect(find('Inner')).toMatch(/^│\s*│\s+Inner\s+│/)
171
- expect(find('Inner')).toMatch(/│$/)
172
- expect(find('Alpha')).toMatch(/^│\s*│\s*│\s+Alpha/)
173
- expect(find('Beta')).toMatch(/^│.*Beta.*│$/)
174
- })
175
-
176
- it('ASCII draws a junction as a small box and keeps its edge arrow', () => {
177
- const out = renderMermaidASCII(NESTED)
178
- expect(out).toContain('●')
179
- expect(out).toContain('►')
180
- })
181
-
182
- it('SVG and ASCII both render {group} edges', () => {
183
- const src = `architecture-beta
184
- group g(cloud)[Group]
185
- service a[Alpha] in g
186
- service b[Beta]
187
- a{group}:R --> L:b`
188
- expect(renderMermaidSVG(src)).toContain('data-id="g"')
189
- const out = renderMermaidASCII(src)
190
- expect(out).toContain('Group')
191
- expect(out).toContain('Beta')
192
- })
193
-
194
- it('SVG reversed edges still render', () => {
195
- const svg = renderMermaidSVG(
196
- 'architecture-beta\nservice a[Alpha]\nservice b[Beta]\na:L --> R:b',
197
- )
198
- expect(svg).toContain('data-id="a"')
199
- expect(svg.match(/class="edge"/g)).toHaveLength(1)
200
- })
201
-
202
- // https://github.com/dfadler/zombie-mermaid/issues/1197: a back-edge across
203
- // sibling groups used to throw in the ASCII grid layout.
204
- it('ASCII renders a back-edge across sibling groups (#1197)', () => {
205
- const out = renderMermaidASCII(`architecture-beta
206
- group g1(cloud)[G1]
207
- group g2(cloud)[G2]
208
- group g3(cloud)[G3]
209
- service a(server)[A] in g1
210
- service b(server)[B] in g2
211
- service c(server)[C] in g3
212
- a:R --> L:b
213
- b:R --> L:c
214
- c:B --> B:a`)
215
- for (const g of ['G1', 'G2', 'G3']) expect(out).toContain(g)
216
- })
217
- })