zombie-mermaid 4.2.3 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -14
- package/dist/cli.js +93 -90
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2 -2
- package/package.json +8 -8
- package/src/ascii-entry.ts +0 -14
- package/src/browser.ts +0 -53
- package/src/cli/html-viewer-client-source.ts +0 -13
- package/src/cli/html-viewer-client.js +0 -292
- package/src/cli/html-viewer.ts +0 -179
- package/src/cli/mcp.ts +0 -36
- package/src/cli/parse-args.ts +0 -531
- package/src/cli/png.ts +0 -38
- package/src/cli/render.ts +0 -398
- package/src/cli/web.ts +0 -235
- package/src/cli.ts +0 -150
- package/src/index.ts +0 -57
- package/src/mcp-entry.ts +0 -21
- package/src/package-info.ts +0 -30
package/README.md
CHANGED
|
@@ -54,21 +54,22 @@ automatically with every release:
|
|
|
54
54
|
and `@zombie-mermaid/mermaid-parser`. It has no third-party dependencies, so
|
|
55
55
|
this is what `zombie-mermaid/ascii` costs.
|
|
56
56
|
- **svg-renderer (incl. deps)** — the SVG renderer, core and parser, **plus its
|
|
57
|
-
third-party dependencies
|
|
58
|
-
[ELK.js](https://github.com/kieler/elkjs)
|
|
59
|
-
gzipped on its own,
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
third-party dependencies**, reported two ways: the base figure, and the figure
|
|
58
|
+
with [ELK.js](https://github.com/kieler/elkjs) (the layout engine) registered.
|
|
59
|
+
ELK.js is an optional peer: about 466 KB gzipped on its own, one pre-bundled
|
|
60
|
+
file that can't be tree-shaken, and only shipped if your app registers it
|
|
61
|
+
(see [the migration guide](docs/guides/elkjs-optional-peer.md)). `entities` is
|
|
62
|
+
counted tree-shaken, since the renderer uses one function from it.
|
|
62
63
|
|
|
63
64
|
Both figures gzip a plain concatenation of the built files, so they approximate
|
|
64
65
|
what you'd ship, not what any particular bundler emits. The umbrella
|
|
65
66
|
`zombie-mermaid` entry re-exports both renderers; its all-in total is
|
|
66
67
|
[](#bundle-size), the worst case. With a
|
|
67
68
|
bundler, importing only `renderMermaidASCII` from the root drops the SVG
|
|
68
|
-
renderer
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
(see [ASCII Output](#ascii-output)).
|
|
69
|
+
renderer (every package here is `"sideEffects": false`), and the root entry no
|
|
70
|
+
longer includes ELK.js unless you register it. Without a bundler — Node, a CLI, a
|
|
71
|
+
serverless function — you can import from `zombie-mermaid/ascii` to skip loading
|
|
72
|
+
the SVG renderer at all (see [ASCII Output](#ascii-output)).
|
|
72
73
|
|
|
73
74
|
## Features
|
|
74
75
|
|
|
@@ -93,6 +94,10 @@ bun add zombie-mermaid
|
|
|
93
94
|
pnpm add zombie-mermaid
|
|
94
95
|
```
|
|
95
96
|
|
|
97
|
+
> **Upgrading from 4.x?** `elkjs` is now an optional peer dependency: browser and
|
|
98
|
+
> bundler apps must call `registerElk(ELK)` once. See the
|
|
99
|
+
> [migration guide](docs/guides/elkjs-optional-peer.md).
|
|
100
|
+
|
|
96
101
|
Only need one output format? `@zombie-mermaid/ascii-renderer` and `@zombie-mermaid/svg-renderer` are published standalone — see [Packages](#packages) below.
|
|
97
102
|
|
|
98
103
|
## Quick Start
|
|
@@ -112,6 +117,22 @@ const svg = renderMermaidSVG(`
|
|
|
112
117
|
|
|
113
118
|
Rendering is **fully synchronous** — no `await`, no promises. The ELK.js layout engine runs synchronously via a FakeWorker bypass, so you get your SVG string instantly.
|
|
114
119
|
|
|
120
|
+
Flowchart, state, class, ER and architecture diagrams are laid out by
|
|
121
|
+
[`elkjs`](https://github.com/kieler/elkjs), an **optional peer dependency**.
|
|
122
|
+
Under Node and Bun it is loaded automatically. In a browser or bundler, register
|
|
123
|
+
it once (`npm install elkjs`):
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import ELK from 'elkjs/lib/elk.bundled.js'
|
|
127
|
+
import { registerElk } from 'zombie-mermaid'
|
|
128
|
+
|
|
129
|
+
registerElk(ELK)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Sequence, pie, xychart and C4 diagrams, and all ASCII output, need no `elkjs`
|
|
133
|
+
and no registration. Rendering a graph diagram with no `elkjs` available throws an
|
|
134
|
+
`ElkNotRegisteredError` that says how to fix it.
|
|
135
|
+
|
|
115
136
|
Need async? Use `renderMermaidSVGAsync()` — same output, returns a `Promise<string>`.
|
|
116
137
|
|
|
117
138
|
### ASCII Output
|
|
@@ -131,10 +152,9 @@ const ascii = renderMermaidASCII(`graph LR; A --> B --> C`)
|
|
|
131
152
|
```
|
|
132
153
|
|
|
133
154
|
ASCII-only consumers (a CLI, a terminal UI, a serverless function) can import
|
|
134
|
-
from `zombie-mermaid/ascii` instead of the package root. The root entry
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
it:
|
|
155
|
+
from `zombie-mermaid/ascii` instead of the package root. The root entry also
|
|
156
|
+
loads the SVG renderer (about 74 KB gzipped, plus `elkjs` only if you register
|
|
157
|
+
it); the `/ascii` subpath never touches either:
|
|
138
158
|
|
|
139
159
|
```typescript
|
|
140
160
|
import { renderMermaidASCII } from 'zombie-mermaid/ascii'
|
|
@@ -234,7 +254,7 @@ the package.
|
|
|
234
254
|
|
|
235
255
|
This repo is a pnpm-workspace monorepo. Most consumers only need the umbrella `zombie-mermaid` package above; internally it's built from workspace packages under `packages/`, all published under the `@zombie-mermaid` npm scope and version-locked with it:
|
|
236
256
|
|
|
237
|
-
- **[`@zombie-mermaid/ascii-renderer`](packages/ascii-renderer)** — the ASCII/Unicode renderer, published standalone for anyone who wants terminal output without `svg-renderer`
|
|
257
|
+
- **[`@zombie-mermaid/ascii-renderer`](packages/ascii-renderer)** — the ASCII/Unicode renderer, published standalone for anyone who wants terminal output without `svg-renderer` or `elkjs`. The exact code `zombie-mermaid/ascii` re-exports.
|
|
238
258
|
[](https://www.npmjs.com/package/@zombie-mermaid/ascii-renderer) [](#bundle-size)
|
|
239
259
|
- **[`@zombie-mermaid/svg-renderer`](packages/svg-renderer)** — the ELK.js-backed SVG layout and rendering engine, also published standalone.
|
|
240
260
|
[](https://www.npmjs.com/package/@zombie-mermaid/svg-renderer) [](#bundle-size)
|
package/dist/cli.js
CHANGED
|
@@ -5,11 +5,12 @@ import { THEMES as B, escapeXml as q, isDirection as j, isWideChar as K } from "
|
|
|
5
5
|
import { access as J, readFile as Z, writeFile as Q } from "node:fs/promises";
|
|
6
6
|
import { diagramColorsToAsciiTheme as ee, renderMermaidASCII as O } from "@zombie-mermaid/ascii-renderer";
|
|
7
7
|
import "@zombie-mermaid/mermaid-parser";
|
|
8
|
-
import { renderMermaidSVG as z } from "@zombie-mermaid/svg-renderer";
|
|
9
|
-
import { createServer as
|
|
10
|
-
import { StdioServerTransport as
|
|
11
|
-
import { createMcpServer as
|
|
12
|
-
|
|
8
|
+
import { registerElk as te, renderMermaidSVG as z } from "@zombie-mermaid/svg-renderer";
|
|
9
|
+
import { createServer as ne } from "node:http";
|
|
10
|
+
import { StdioServerTransport as re } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { createMcpServer as oe } from "@zombie-mermaid/mcp";
|
|
12
|
+
import ie from "elkjs/lib/elk.bundled.js";
|
|
13
|
+
var ae = 3e3;
|
|
13
14
|
var W = {
|
|
14
15
|
".svg": "svg",
|
|
15
16
|
".txt": "ascii",
|
|
@@ -17,7 +18,7 @@ var W = {
|
|
|
17
18
|
".htm": "html",
|
|
18
19
|
".png": "png"
|
|
19
20
|
};
|
|
20
|
-
function
|
|
21
|
+
function se(e) {
|
|
21
22
|
if (!(e === void 0 || e === "-"))
|
|
22
23
|
return W[V(e).toLowerCase()];
|
|
23
24
|
}
|
|
@@ -44,7 +45,7 @@ var v = {
|
|
|
44
45
|
label: "the PNG rasterization"
|
|
45
46
|
}
|
|
46
47
|
}, A = Object.keys(v);
|
|
47
|
-
function
|
|
48
|
+
function de(e, n) {
|
|
48
49
|
const t = G(e);
|
|
49
50
|
return H({
|
|
50
51
|
dir: t.dir,
|
|
@@ -52,24 +53,24 @@ function ae(e, n) {
|
|
|
52
53
|
ext: n
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
|
-
function
|
|
56
|
+
function ce(e) {
|
|
56
57
|
const [n, ...t] = e;
|
|
57
58
|
if (n === void 0) return { command: "help" };
|
|
58
59
|
if (n === "--help" || n === "-h") return { command: "help" };
|
|
59
60
|
if (n === "--version" || n === "-v") return { command: "version" };
|
|
60
61
|
if (n === "themes") return { command: "themes" };
|
|
61
|
-
if (n === "render") return
|
|
62
|
-
if (n === "web") return
|
|
62
|
+
if (n === "render") return ue(t);
|
|
63
|
+
if (n === "web") return pe(t);
|
|
63
64
|
if (n === "mcp") return { command: "mcp" };
|
|
64
65
|
throw new Error(`Unknown command: ${n}`);
|
|
65
66
|
}
|
|
66
|
-
function
|
|
67
|
+
function $(e, n, t) {
|
|
67
68
|
const r = e[n + 1];
|
|
68
69
|
if (n + 1 >= e.length || r === void 0) throw new Error(`${t} requires a numeric value`);
|
|
69
70
|
if (!/^\d+$/.test(r)) throw new Error(`${t} requires a non-negative integer, got: "${r}"`);
|
|
70
71
|
return Number(r);
|
|
71
72
|
}
|
|
72
|
-
function
|
|
73
|
+
function le(e, n, t) {
|
|
73
74
|
const r = e[n + 1];
|
|
74
75
|
if (n + 1 >= e.length || r === void 0) throw new Error(`${t} requires a value ("auto" or a positive integer)`);
|
|
75
76
|
if (r === "auto") return "auto";
|
|
@@ -77,14 +78,14 @@ function de(e, n, t) {
|
|
|
77
78
|
if (!/^\d+$/.test(r) || s === 0 || !Number.isSafeInteger(s)) throw new Error(`${t} requires "auto" or a positive integer, got: "${r}"`);
|
|
78
79
|
return s;
|
|
79
80
|
}
|
|
80
|
-
function
|
|
81
|
+
function me(e, n, t) {
|
|
81
82
|
const r = e[n + 1];
|
|
82
83
|
if (n + 1 >= e.length || r === void 0) throw new Error(`${t} requires a value (one of TD, TB, BT, LR, RL)`);
|
|
83
84
|
const s = r.toUpperCase();
|
|
84
85
|
if (!j(s)) throw new Error(`${t} requires one of TD, TB, BT, LR, RL, got: "${r}"`);
|
|
85
86
|
return s;
|
|
86
87
|
}
|
|
87
|
-
function
|
|
88
|
+
function ue(e) {
|
|
88
89
|
let n, t = !1, r = !1, s = !1, m = !1, c = !1, d, E = !1, S, k, g, C, T = !1, b = !1, a, u, i = 0;
|
|
89
90
|
for (; i < e.length; ) {
|
|
90
91
|
const o = e[i];
|
|
@@ -108,19 +109,19 @@ function le(e) {
|
|
|
108
109
|
if (i + 1 >= e.length) throw new Error("--theme requires a theme name");
|
|
109
110
|
S = e[i + 1], i += 2;
|
|
110
111
|
} else if (o === "-x" || o === "--paddingX")
|
|
111
|
-
k =
|
|
112
|
+
k = $(e, i, o), i += 2;
|
|
112
113
|
else if (o === "-y" || o === "--paddingY")
|
|
113
|
-
g =
|
|
114
|
+
g = $(e, i, o), i += 2;
|
|
114
115
|
else if (o === "-p" || o === "--borderPadding")
|
|
115
|
-
C =
|
|
116
|
+
C = $(e, i, o), i += 2;
|
|
116
117
|
else if (o === "--coords")
|
|
117
118
|
T = !0, i++;
|
|
118
119
|
else if (o === "--hyperlinks")
|
|
119
120
|
b = !0, i++;
|
|
120
121
|
else if (o === "-w" || o === "--max-width")
|
|
121
|
-
a =
|
|
122
|
+
a = le(e, i, o), i += 2;
|
|
122
123
|
else if (o === "--direction")
|
|
123
|
-
u =
|
|
124
|
+
u = me(e, i, o), i += 2;
|
|
124
125
|
else if (!o.startsWith("-") || o === "-") {
|
|
125
126
|
if (o === "-") throw new Error("Unexpected argument: - (use -o - to write output to stdout; omit the input file to read stdin)");
|
|
126
127
|
if (n !== void 0) throw new Error(`Unexpected argument: ${o} (input file already set to "${n}")`);
|
|
@@ -136,7 +137,7 @@ function le(e) {
|
|
|
136
137
|
const [o, l] = w;
|
|
137
138
|
throw new Error(`${v[o].flag} and ${v[l].flag} cannot both be set — they would write different content to the same output path. Run the command twice with different -o paths for each.`);
|
|
138
139
|
}
|
|
139
|
-
const p =
|
|
140
|
+
const p = se(d);
|
|
140
141
|
if (p !== void 0 && p !== "ascii") {
|
|
141
142
|
const o = A.find((l) => l !== p && h[l]);
|
|
142
143
|
if (o !== void 0) {
|
|
@@ -171,7 +172,7 @@ function le(e) {
|
|
|
171
172
|
if (f !== void 0 && d === void 0) {
|
|
172
173
|
const { flag: o, ext: l } = v[f];
|
|
173
174
|
if (n === void 0) throw new Error(`${o} needs -o <path> (or -o - for stdout) when reading from stdin — there is no input file name to derive an output name from`);
|
|
174
|
-
d =
|
|
175
|
+
d = de(n, l);
|
|
175
176
|
}
|
|
176
177
|
if (a !== void 0 && !t) throw new Error("-w/--max-width requires --ascii");
|
|
177
178
|
if (b && !t) throw new Error("--hyperlinks requires --ascii");
|
|
@@ -196,13 +197,13 @@ function le(e) {
|
|
|
196
197
|
direction: u
|
|
197
198
|
};
|
|
198
199
|
}
|
|
199
|
-
function
|
|
200
|
-
let n =
|
|
200
|
+
function pe(e) {
|
|
201
|
+
let n = ae, t = 0;
|
|
201
202
|
for (; t < e.length; ) {
|
|
202
203
|
const r = e[t];
|
|
203
204
|
if (r === void 0) throw new Error(`parseArgs: index ${t} out of range while parsing arguments`);
|
|
204
205
|
if (r === "--port")
|
|
205
|
-
n =
|
|
206
|
+
n = $(e, t, r), t += 2;
|
|
206
207
|
else throw new Error(`Unknown flag: ${r}`);
|
|
207
208
|
}
|
|
208
209
|
return {
|
|
@@ -210,33 +211,34 @@ function me(e) {
|
|
|
210
211
|
port: n
|
|
211
212
|
};
|
|
212
213
|
}
|
|
213
|
-
var
|
|
214
|
-
function
|
|
215
|
-
return
|
|
214
|
+
var he = /\p{Mn}|\p{Me}/u;
|
|
215
|
+
function fe(e) {
|
|
216
|
+
return he.test(e);
|
|
216
217
|
}
|
|
217
|
-
var
|
|
218
|
-
function
|
|
218
|
+
var ge = new Intl.Segmenter(void 0, { granularity: "grapheme" }), ve = "️";
|
|
219
|
+
function we(e) {
|
|
220
|
+
if (/^[\x20-\x7e]*$/.test(e)) return e.split("");
|
|
219
221
|
const n = [];
|
|
220
|
-
for (const { segment: t } of
|
|
222
|
+
for (const { segment: t } of ge.segment(e)) n.push(t);
|
|
221
223
|
return n;
|
|
222
224
|
}
|
|
223
|
-
function
|
|
224
|
-
if (e.includes(
|
|
225
|
+
function be(e) {
|
|
226
|
+
if (e.includes(ve)) return 2;
|
|
225
227
|
let n = !1, t = !1;
|
|
226
228
|
for (const r of e)
|
|
227
|
-
K(r) && (n = !0),
|
|
229
|
+
K(r) && (n = !0), fe(r) || (t = !0);
|
|
228
230
|
return n ? 2 : t ? 1 : 0;
|
|
229
231
|
}
|
|
230
|
-
function
|
|
232
|
+
function ye(e) {
|
|
231
233
|
let n = 0;
|
|
232
|
-
for (const t of
|
|
234
|
+
for (const t of we(e)) n += be(t);
|
|
233
235
|
return n;
|
|
234
236
|
}
|
|
235
|
-
var
|
|
236
|
-
function
|
|
237
|
-
return e.replace(
|
|
237
|
+
var xe = /\x1b\]8;[^\x07\x1b]*(?:\x1b\\|\x07)/g;
|
|
238
|
+
function Ee(e) {
|
|
239
|
+
return e.replace(xe, "");
|
|
238
240
|
}
|
|
239
|
-
var
|
|
241
|
+
var Se = `// @ts-check
|
|
240
242
|
/// <reference lib="dom" />
|
|
241
243
|
// ============================================================================
|
|
242
244
|
// Client script for the CLI's self-contained HTML viewer (\`render --html\`).
|
|
@@ -528,7 +530,7 @@ var xe = `// @ts-check
|
|
|
528
530
|
fit()
|
|
529
531
|
stage.focus({ preventScroll: true })
|
|
530
532
|
})()
|
|
531
|
-
`,
|
|
533
|
+
`, ke = `
|
|
532
534
|
:root {
|
|
533
535
|
color-scheme: light dark;
|
|
534
536
|
--bg: #f4f4f5;
|
|
@@ -635,7 +637,7 @@ var xe = `// @ts-check
|
|
|
635
637
|
#diagram { position: static; transform: none !important; }
|
|
636
638
|
}
|
|
637
639
|
`.trim();
|
|
638
|
-
function
|
|
640
|
+
function Ce(e) {
|
|
639
641
|
const n = e.title?.trim() || "Mermaid diagram";
|
|
640
642
|
return `<!doctype html>
|
|
641
643
|
<html lang="en">
|
|
@@ -644,7 +646,7 @@ function Se(e) {
|
|
|
644
646
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
645
647
|
<title>${q(n)}</title>
|
|
646
648
|
<style>
|
|
647
|
-
${
|
|
649
|
+
${ke}
|
|
648
650
|
</style>
|
|
649
651
|
</head>
|
|
650
652
|
<body>
|
|
@@ -662,13 +664,13 @@ ${e.svg}
|
|
|
662
664
|
<button id="theme" type="button" aria-pressed="false" aria-label="Switch to dark mode (T)">Dark</button>
|
|
663
665
|
</div>
|
|
664
666
|
<script>
|
|
665
|
-
${
|
|
667
|
+
${Se}
|
|
666
668
|
<\/script>
|
|
667
669
|
</body>
|
|
668
670
|
</html>
|
|
669
671
|
`;
|
|
670
672
|
}
|
|
671
|
-
async function
|
|
673
|
+
async function Te(e) {
|
|
672
674
|
let n;
|
|
673
675
|
try {
|
|
674
676
|
n = await import("@resvg/resvg-js");
|
|
@@ -679,22 +681,22 @@ ${r}`);
|
|
|
679
681
|
}
|
|
680
682
|
return (await n.renderAsync(e)).asPng();
|
|
681
683
|
}
|
|
682
|
-
var
|
|
684
|
+
var Ae = 80, P = 1, L = 1, R = 0, Ie = /\x1b\[[0-9;]*m/g;
|
|
683
685
|
function D(e) {
|
|
684
686
|
return e.split(`
|
|
685
|
-
`).reduce((n, t) => Math.max(n,
|
|
687
|
+
`).reduce((n, t) => Math.max(n, ye(Ee(t.replace(Ie, "")))), 0);
|
|
686
688
|
}
|
|
687
|
-
function
|
|
688
|
-
return e !== "auto" ? e : process.stdout.columns ??
|
|
689
|
+
function Me(e) {
|
|
690
|
+
return e !== "auto" ? e : process.stdout.columns ?? Ae;
|
|
689
691
|
}
|
|
690
|
-
async function
|
|
692
|
+
async function ze(e, n, t, r) {
|
|
691
693
|
const s = n ?? process.stdout, m = r ?? process.stderr;
|
|
692
694
|
let c;
|
|
693
695
|
if (e.input !== void 0) c = await Z(e.input, "utf-8");
|
|
694
696
|
else if (t !== void 0) c = t;
|
|
695
697
|
else {
|
|
696
698
|
if (process.stdin.isTTY) throw new Error("No input file specified and stdin is a terminal. Pipe a diagram or pass a file path.");
|
|
697
|
-
c = await
|
|
699
|
+
c = await Le();
|
|
698
700
|
}
|
|
699
701
|
if (c = c.trim(), c.length === 0) throw new Error("Empty input — provide a Mermaid diagram via file or stdin");
|
|
700
702
|
let d;
|
|
@@ -708,7 +710,7 @@ async function Ie(e, n, t, r) {
|
|
|
708
710
|
C,
|
|
709
711
|
T,
|
|
710
712
|
b
|
|
711
|
-
]) a !== void 0 && await
|
|
713
|
+
]) a !== void 0 && await $e(a, e.force);
|
|
712
714
|
if (e.ascii) {
|
|
713
715
|
const a = d && g === void 0 ? {
|
|
714
716
|
colorMode: "auto",
|
|
@@ -717,10 +719,10 @@ async function Ie(e, n, t, r) {
|
|
|
717
719
|
e.paddingX !== void 0 && (a.paddingX = e.paddingX), e.paddingY !== void 0 && (a.paddingY = e.paddingY), e.borderPadding !== void 0 && (a.boxBorderPadding = e.borderPadding), e.coords && (a.showCoords = !0), e.direction !== void 0 && (a.direction = e.direction), e.hyperlinks && g === void 0 && (a.hyperlinks = !0);
|
|
718
720
|
let u = O(c, a);
|
|
719
721
|
if (e.maxWidth !== void 0) {
|
|
720
|
-
const i =
|
|
722
|
+
const i = Me(e.maxWidth);
|
|
721
723
|
let h = D(u), w = !1;
|
|
722
724
|
if (h > i) {
|
|
723
|
-
const p = a.paddingX ?? 5, y = a.paddingY ?? 5, f = a.boxBorderPadding ?? 1, o = Math.min(p,
|
|
725
|
+
const p = a.paddingX ?? 5, y = a.paddingY ?? 5, f = a.boxBorderPadding ?? 1, o = Math.min(p, P), l = Math.min(y, L), x = Math.min(f, R);
|
|
724
726
|
if (o < p || l < y || x < f) {
|
|
725
727
|
const _ = O(c, {
|
|
726
728
|
...a,
|
|
@@ -732,10 +734,10 @@ async function Ie(e, n, t, r) {
|
|
|
732
734
|
}
|
|
733
735
|
}
|
|
734
736
|
if (h > i) {
|
|
735
|
-
const p = e.maxWidth === "auto" ? "detected terminal width" : "--max-width", y = w ? `Compact spacing (-x ${
|
|
737
|
+
const p = e.maxWidth === "auto" ? "detected terminal width" : "--max-width", y = w ? `Compact spacing (-x ${P} -y ${L} -p ${R}) was already applied automatically. ` : "", f = w ? "Try a narrower direction (LR vs TD), shorter labels, or widen your terminal." : "Try -x/-y/-p for tighter spacing, a narrower direction (LR vs TD), or widen your terminal.";
|
|
736
738
|
m.write(`Warning: ASCII output is ${h} columns wide, exceeding ${p} of ${i}. ${y}zombie-mermaid does not reflow diagram structure to fit (no label wrapping or direction-flip cascade — see https://github.com/dfadler/zombie-mermaid/issues/335). ${f}
|
|
737
739
|
`);
|
|
738
|
-
} else w && m.write(`Note: ASCII output exceeded ${i} columns at the requested spacing; applied compact spacing automatically (-x ${
|
|
740
|
+
} else w && m.write(`Note: ASCII output exceeded ${i} columns at the requested spacing; applied compact spacing automatically (-x ${P} -y ${L} -p ${R}) to fit.
|
|
739
741
|
`);
|
|
740
742
|
}
|
|
741
743
|
await M(I(g === void 0, g), u + `
|
|
@@ -751,7 +753,7 @@ async function Ie(e, n, t, r) {
|
|
|
751
753
|
await M(I(E, C), u, s, e.force);
|
|
752
754
|
}
|
|
753
755
|
if (e.html) {
|
|
754
|
-
const a = z(c, d ?? {}), u = e.input ? G(e.input).name : void 0, i =
|
|
756
|
+
const a = z(c, d ?? {}), u = e.input ? G(e.input).name : void 0, i = Ce({
|
|
755
757
|
svg: a,
|
|
756
758
|
title: u
|
|
757
759
|
});
|
|
@@ -763,7 +765,7 @@ async function Ie(e, n, t, r) {
|
|
|
763
765
|
resolveColors: !0
|
|
764
766
|
};
|
|
765
767
|
e.direction !== void 0 && (a.direction = e.direction);
|
|
766
|
-
const u = z(c, a), i = await
|
|
768
|
+
const u = z(c, a), i = await Te(u);
|
|
767
769
|
await M(I(k, b), i, s, e.force);
|
|
768
770
|
}
|
|
769
771
|
}
|
|
@@ -779,13 +781,13 @@ async function M(e, n, t, r) {
|
|
|
779
781
|
t.write(n);
|
|
780
782
|
break;
|
|
781
783
|
case "file":
|
|
782
|
-
await
|
|
784
|
+
await Pe(e.path, n, r);
|
|
783
785
|
}
|
|
784
786
|
}
|
|
785
787
|
function X(e) {
|
|
786
788
|
return /* @__PURE__ */ new Error(`Refusing to overwrite existing file "${e}" — pass --force to replace it`);
|
|
787
789
|
}
|
|
788
|
-
async function
|
|
790
|
+
async function $e(e, n) {
|
|
789
791
|
if (n) return;
|
|
790
792
|
let t = !0;
|
|
791
793
|
try {
|
|
@@ -795,7 +797,7 @@ async function Me(e, n) {
|
|
|
795
797
|
}
|
|
796
798
|
if (t) throw X(e);
|
|
797
799
|
}
|
|
798
|
-
async function
|
|
800
|
+
async function Pe(e, n, t) {
|
|
799
801
|
try {
|
|
800
802
|
await Q(e, n, {
|
|
801
803
|
encoding: "utf-8",
|
|
@@ -805,19 +807,19 @@ async function ze(e, n, t) {
|
|
|
805
807
|
throw !t && r instanceof Error && "code" in r && r.code === "EEXIST" ? X(e) : r;
|
|
806
808
|
}
|
|
807
809
|
}
|
|
808
|
-
async function
|
|
810
|
+
async function Le() {
|
|
809
811
|
const e = [], n = process.stdin;
|
|
810
812
|
return n.setEncoding("utf-8"), new Promise((t, r) => {
|
|
811
813
|
n.on("data", (s) => e.push(s)), n.on("end", () => t(e.join(""))), n.on("error", r);
|
|
812
814
|
});
|
|
813
815
|
}
|
|
814
|
-
var
|
|
815
|
-
function
|
|
816
|
+
var Re = 1e6;
|
|
817
|
+
function Be(e) {
|
|
816
818
|
return new Promise((n, t) => {
|
|
817
819
|
const r = [];
|
|
818
820
|
let s = 0;
|
|
819
821
|
e.on("data", (m) => {
|
|
820
|
-
if (s += m.length, s >
|
|
822
|
+
if (s += m.length, s > Re) {
|
|
821
823
|
t(/* @__PURE__ */ new Error("Request body too large")), e.destroy();
|
|
822
824
|
return;
|
|
823
825
|
}
|
|
@@ -828,7 +830,7 @@ function Le(e) {
|
|
|
828
830
|
function Y(e) {
|
|
829
831
|
return typeof e == "object" && e !== null;
|
|
830
832
|
}
|
|
831
|
-
function
|
|
833
|
+
function Oe(e) {
|
|
832
834
|
let n;
|
|
833
835
|
try {
|
|
834
836
|
n = JSON.parse(e);
|
|
@@ -850,9 +852,9 @@ function F(e, n, t) {
|
|
|
850
852
|
"Content-Length": Buffer.byteLength(r)
|
|
851
853
|
}), e.end(r);
|
|
852
854
|
}
|
|
853
|
-
async function
|
|
855
|
+
async function _e(e, n) {
|
|
854
856
|
try {
|
|
855
|
-
const { source: t, format: r } =
|
|
857
|
+
const { source: t, format: r } = Oe(await Be(e));
|
|
856
858
|
F(n, 200, {
|
|
857
859
|
output: r === "svg" ? z(t) : O(t),
|
|
858
860
|
format: r
|
|
@@ -861,7 +863,7 @@ async function Be(e, n) {
|
|
|
861
863
|
F(n, 400, { error: t instanceof Error ? t.message : String(t) });
|
|
862
864
|
}
|
|
863
865
|
}
|
|
864
|
-
var
|
|
866
|
+
var Ne = `<!doctype html>
|
|
865
867
|
<html lang="en">
|
|
866
868
|
<head>
|
|
867
869
|
<meta charset="utf-8" />
|
|
@@ -927,55 +929,56 @@ var Oe = `<!doctype html>
|
|
|
927
929
|
</body>
|
|
928
930
|
</html>
|
|
929
931
|
`;
|
|
930
|
-
function
|
|
931
|
-
return
|
|
932
|
+
function De() {
|
|
933
|
+
return ne((e, n) => {
|
|
932
934
|
const t = (e.url ?? "/").split("?")[0];
|
|
933
935
|
if (e.method === "GET" && (t === "/" || t === "")) {
|
|
934
|
-
n.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), n.end(
|
|
936
|
+
n.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), n.end(Ne);
|
|
935
937
|
return;
|
|
936
938
|
}
|
|
937
939
|
if (e.method === "POST" && t === "/render") {
|
|
938
|
-
|
|
940
|
+
_e(e, n);
|
|
939
941
|
return;
|
|
940
942
|
}
|
|
941
943
|
n.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" }), n.end("Not found");
|
|
942
944
|
});
|
|
943
945
|
}
|
|
944
|
-
function
|
|
946
|
+
function Fe(e) {
|
|
945
947
|
return new Promise((n, t) => {
|
|
946
|
-
const r =
|
|
948
|
+
const r = De();
|
|
947
949
|
r.once("error", t), r.listen(e, "127.0.0.1", () => {
|
|
948
950
|
r.removeListener("error", t), n(r);
|
|
949
951
|
});
|
|
950
952
|
});
|
|
951
953
|
}
|
|
952
|
-
async function
|
|
953
|
-
const t = await
|
|
954
|
+
async function Ge(e, n = console.log) {
|
|
955
|
+
const t = await Fe(e.port), r = t.address();
|
|
954
956
|
return n(`zombie-mermaid web running at http://localhost:${Y(r) && typeof r.port == "number" ? r.port : e.port}`), t;
|
|
955
957
|
}
|
|
956
|
-
async function
|
|
957
|
-
const n =
|
|
958
|
+
async function We(e = (n) => console.error(n)) {
|
|
959
|
+
const n = oe(), t = new re();
|
|
958
960
|
return await n.connect(t), e("zombie-mermaid MCP server running on stdio (experimental — feedback welcome: https://github.com/dfadler/zombie-mermaid/issues)"), n;
|
|
959
961
|
}
|
|
960
|
-
function
|
|
962
|
+
function Xe() {
|
|
961
963
|
const e = U(import.meta.url)("../package.json");
|
|
962
964
|
return typeof e == "object" && e !== null && "version" in e && typeof e.version == "string" ? e.version : "unknown";
|
|
963
965
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
+
te(ie);
|
|
967
|
+
var Ye = Xe();
|
|
968
|
+
async function Ue() {
|
|
966
969
|
const e = process.argv.slice(2);
|
|
967
970
|
let n;
|
|
968
971
|
try {
|
|
969
|
-
n =
|
|
972
|
+
n = ce(e);
|
|
970
973
|
} catch (t) {
|
|
971
974
|
console.error(`Error: ${t instanceof Error ? t.message : String(t)}`), process.exit(1);
|
|
972
975
|
}
|
|
973
976
|
switch (n.command) {
|
|
974
977
|
case "help":
|
|
975
|
-
|
|
978
|
+
Ve();
|
|
976
979
|
break;
|
|
977
980
|
case "version":
|
|
978
|
-
console.log(`zombie-mermaid ${
|
|
981
|
+
console.log(`zombie-mermaid ${Ye}`);
|
|
979
982
|
break;
|
|
980
983
|
case "themes":
|
|
981
984
|
console.log(`Available themes:
|
|
@@ -984,27 +987,27 @@ async function Xe() {
|
|
|
984
987
|
break;
|
|
985
988
|
case "render":
|
|
986
989
|
try {
|
|
987
|
-
await
|
|
990
|
+
await ze(n);
|
|
988
991
|
} catch (t) {
|
|
989
992
|
console.error(`Error: ${t instanceof Error ? t.message : String(t)}`), process.exit(1);
|
|
990
993
|
}
|
|
991
994
|
break;
|
|
992
995
|
case "web":
|
|
993
996
|
try {
|
|
994
|
-
await
|
|
997
|
+
await Ge(n);
|
|
995
998
|
} catch (t) {
|
|
996
999
|
console.error(`Error: ${t instanceof Error ? t.message : String(t)}`), process.exit(1);
|
|
997
1000
|
}
|
|
998
1001
|
break;
|
|
999
1002
|
case "mcp":
|
|
1000
1003
|
try {
|
|
1001
|
-
await
|
|
1004
|
+
await We();
|
|
1002
1005
|
} catch (t) {
|
|
1003
1006
|
console.error(`Error: ${t instanceof Error ? t.message : String(t)}`), process.exit(1);
|
|
1004
1007
|
}
|
|
1005
1008
|
}
|
|
1006
1009
|
}
|
|
1007
|
-
function
|
|
1010
|
+
function Ve() {
|
|
1008
1011
|
console.log(`
|
|
1009
1012
|
zombie-mermaid — render Mermaid diagrams from the command line
|
|
1010
1013
|
|
|
@@ -1078,7 +1081,7 @@ Options:
|
|
|
1078
1081
|
-v, --version Show version
|
|
1079
1082
|
`.trim());
|
|
1080
1083
|
}
|
|
1081
|
-
|
|
1084
|
+
Ue();
|
|
1082
1085
|
export {
|
|
1083
|
-
|
|
1086
|
+
Ue as main
|
|
1084
1087
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@zombie-mermaid/core"),t=require("@zombie-mermaid/mermaid-parser"),n=require("@zombie-mermaid/ascii-renderer"),r=require("@zombie-mermaid/svg-renderer");Object.defineProperty(exports,"DEFAULTS",{enumerable:!0,get:function(){return e.DEFAULTS}}),Object.defineProperty(exports,"THEMES",{enumerable:!0,get:function(){return e.THEMES}}),Object.defineProperty(exports,"createLayoutCache",{enumerable:!0,get:function(){return r.createLayoutCache}}),Object.defineProperty(exports,"fromShikiTheme",{enumerable:!0,get:function(){return e.fromShikiTheme}}),Object.defineProperty(exports,"parseMermaid",{enumerable:!0,get:function(){return t.parseMermaid}}),Object.defineProperty(exports,"renderMermaid",{enumerable:!0,get:function(){return r.renderMermaid}}),Object.defineProperty(exports,"renderMermaidASCII",{enumerable:!0,get:function(){return n.renderMermaidASCII}}),Object.defineProperty(exports,"renderMermaidAscii",{enumerable:!0,get:function(){return n.renderMermaidAscii}}),Object.defineProperty(exports,"renderMermaidSVG",{enumerable:!0,get:function(){return r.renderMermaidSVG}}),Object.defineProperty(exports,"renderMermaidSVGAsync",{enumerable:!0,get:function(){return r.renderMermaidSVGAsync}}),Object.defineProperty(exports,"renderMermaidSync",{enumerable:!0,get:function(){return r.renderMermaidSync}}),Object.defineProperty(exports,"themeCssVariables",{enumerable:!0,get:function(){return r.themeCssVariables}});
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@zombie-mermaid/core"),t=require("@zombie-mermaid/mermaid-parser"),n=require("@zombie-mermaid/ascii-renderer"),r=require("@zombie-mermaid/svg-renderer");Object.defineProperty(exports,"DEFAULTS",{enumerable:!0,get:function(){return e.DEFAULTS}}),Object.defineProperty(exports,"ElkNotRegisteredError",{enumerable:!0,get:function(){return r.ElkNotRegisteredError}}),Object.defineProperty(exports,"THEMES",{enumerable:!0,get:function(){return e.THEMES}}),Object.defineProperty(exports,"createLayoutCache",{enumerable:!0,get:function(){return r.createLayoutCache}}),Object.defineProperty(exports,"fromShikiTheme",{enumerable:!0,get:function(){return e.fromShikiTheme}}),Object.defineProperty(exports,"parseMermaid",{enumerable:!0,get:function(){return t.parseMermaid}}),Object.defineProperty(exports,"registerElk",{enumerable:!0,get:function(){return r.registerElk}}),Object.defineProperty(exports,"renderMermaid",{enumerable:!0,get:function(){return r.renderMermaid}}),Object.defineProperty(exports,"renderMermaidASCII",{enumerable:!0,get:function(){return n.renderMermaidASCII}}),Object.defineProperty(exports,"renderMermaidAscii",{enumerable:!0,get:function(){return n.renderMermaidAscii}}),Object.defineProperty(exports,"renderMermaidSVG",{enumerable:!0,get:function(){return r.renderMermaidSVG}}),Object.defineProperty(exports,"renderMermaidSVGAsync",{enumerable:!0,get:function(){return r.renderMermaidSVGAsync}}),Object.defineProperty(exports,"renderMermaidSync",{enumerable:!0,get:function(){return r.renderMermaidSync}}),Object.defineProperty(exports,"themeCssVariables",{enumerable:!0,get:function(){return r.themeCssVariables}});
|
package/dist/index.d.cts
CHANGED
|
@@ -5,6 +5,8 @@ import { createLayoutCache } from '@zombie-mermaid/svg-renderer';
|
|
|
5
5
|
import { DEFAULTS } from '@zombie-mermaid/core';
|
|
6
6
|
import { DiagramColors } from '@zombie-mermaid/core';
|
|
7
7
|
import { Direction } from '@zombie-mermaid/core';
|
|
8
|
+
import { ElkConstructor } from '@zombie-mermaid/core';
|
|
9
|
+
import { ElkNotRegisteredError } from '@zombie-mermaid/svg-renderer';
|
|
8
10
|
import { ErRenderOptions } from '@zombie-mermaid/core';
|
|
9
11
|
import { FlowchartRenderOptions } from '@zombie-mermaid/core';
|
|
10
12
|
import { fromShikiTheme } from '@zombie-mermaid/core';
|
|
@@ -13,6 +15,7 @@ import { MermaidGraph } from '@zombie-mermaid/core';
|
|
|
13
15
|
import { NodeInteraction } from '@zombie-mermaid/core';
|
|
14
16
|
import { parseMermaid } from '@zombie-mermaid/mermaid-parser';
|
|
15
17
|
import { PositionedGraph } from '@zombie-mermaid/core';
|
|
18
|
+
import { registerElk } from '@zombie-mermaid/svg-renderer';
|
|
16
19
|
import { renderMermaid } from '@zombie-mermaid/svg-renderer';
|
|
17
20
|
import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer';
|
|
18
21
|
import { renderMermaidAscii } from '@zombie-mermaid/ascii-renderer';
|
|
@@ -40,6 +43,10 @@ export { DiagramColors }
|
|
|
40
43
|
|
|
41
44
|
export { Direction }
|
|
42
45
|
|
|
46
|
+
export { ElkConstructor }
|
|
47
|
+
|
|
48
|
+
export { ElkNotRegisteredError }
|
|
49
|
+
|
|
43
50
|
export { ErRenderOptions }
|
|
44
51
|
|
|
45
52
|
export { FlowchartRenderOptions }
|
|
@@ -56,6 +63,8 @@ export { parseMermaid }
|
|
|
56
63
|
|
|
57
64
|
export { PositionedGraph }
|
|
58
65
|
|
|
66
|
+
export { registerElk }
|
|
67
|
+
|
|
59
68
|
export { renderMermaid }
|
|
60
69
|
|
|
61
70
|
export { renderMermaidASCII }
|