@mermaid-js/mermaid-cli 10.0.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/fa-brands-400-a3b98177.svg +3717 -0
- package/dist/assets/fa-regular-400-be0a0849.svg +801 -0
- package/dist/assets/fa-solid-900-9674eb1b.svg +5034 -0
- package/dist/index.html +337 -280
- package/dist-types/src/cli.d.ts +3 -0
- package/dist-types/src/cli.d.ts.map +1 -0
- package/dist-types/src/index.d.ts +110 -0
- package/dist-types/src/index.d.ts.map +1 -0
- package/package.json +12 -7
- package/src/index.js +108 -38
- package/dist/assets/fa-brands-400-ce2af7e2.svg +0 -1100
- package/dist/assets/fa-regular-400-e519b693.svg +0 -368
- package/dist/assets/fa-solid-900-3e918c25.svg +0 -1892
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options to pass to {@link parseMMD }
|
|
3
|
+
*/
|
|
4
|
+
export type ParseMDDOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* - Puppeteer viewport (e.g. `width`, `height`, `deviceScaleFactor`)
|
|
7
|
+
*/
|
|
8
|
+
viewport?: puppeteer.Viewport | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* - Background color.
|
|
11
|
+
*/
|
|
12
|
+
backgroundColor?: string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* - Mermaid config.
|
|
15
|
+
*/
|
|
16
|
+
mermaidConfig?: any;
|
|
17
|
+
/**
|
|
18
|
+
* - Optional CSS text.
|
|
19
|
+
*/
|
|
20
|
+
myCSS?: string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* - If set, scale PDF to fit chart.
|
|
23
|
+
*/
|
|
24
|
+
pdfFit?: boolean | undefined;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Markdown image properties
|
|
28
|
+
* Used to create an markdown image that looks like ``
|
|
29
|
+
*/
|
|
30
|
+
export type MarkdownImageProps = {
|
|
31
|
+
/**
|
|
32
|
+
* - Path to image.
|
|
33
|
+
*/
|
|
34
|
+
url: string;
|
|
35
|
+
/**
|
|
36
|
+
* - Image alt text, required.
|
|
37
|
+
*/
|
|
38
|
+
alt: string;
|
|
39
|
+
/**
|
|
40
|
+
* - Optional image title text.
|
|
41
|
+
*/
|
|
42
|
+
title?: string | null | undefined;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Renders a mermaid diagram or mermaid markdown file.
|
|
46
|
+
*
|
|
47
|
+
* @param {`${string}.${"md" | "markdown"}` | string | undefined} input - If this ends with `.md`/`.markdown`,
|
|
48
|
+
* path to a markdown file containing mermaid.
|
|
49
|
+
* If this is a string, loads the mermaid definition from the given file.
|
|
50
|
+
* If this is `undefined`, loads the mermaid definition from stdin.
|
|
51
|
+
* @param {`${string}.${"md" | "markdown" | "svg" | "png" | "pdf"}`} output - Path to the output file.
|
|
52
|
+
* @param {Object} [opts] - Options
|
|
53
|
+
* @param {import("puppeteer").LaunchOptions} [opts.puppeteerConfig] - Puppeteer launch options.
|
|
54
|
+
* @param {boolean} [opts.quiet] - If set, suppress log output.
|
|
55
|
+
* @param {"svg" | "png" | "pdf"} [opts.outputFormat] - Mermaid output format.
|
|
56
|
+
* Defaults to `output` extension. Overrides `output` extension if set.
|
|
57
|
+
* @param {ParseMDDOptions} [opts.parseMMDOptions] - Options to pass to {@link parseMMDOptions}.
|
|
58
|
+
*/
|
|
59
|
+
export function run(input: `${string}.${"md" | "markdown"}` | string | undefined, output: `${string}.${"md" | "markdown" | "svg" | "png" | "pdf"}`, { puppeteerConfig, quiet, outputFormat, parseMMDOptions }?: {
|
|
60
|
+
puppeteerConfig?: puppeteer.LaunchOptions | undefined;
|
|
61
|
+
quiet?: boolean | undefined;
|
|
62
|
+
outputFormat?: "svg" | "png" | "pdf" | undefined;
|
|
63
|
+
parseMMDOptions?: ParseMDDOptions | undefined;
|
|
64
|
+
} | undefined): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Render a mermaid diagram.
|
|
67
|
+
*
|
|
68
|
+
* @param {import("puppeteer").Browser} browser - Puppeteer Browser
|
|
69
|
+
* @param {string} definition - Mermaid diagram definition
|
|
70
|
+
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
71
|
+
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
72
|
+
* @returns {Promise<{title: string | null, desc: string | null, data: Buffer}>} The output file in bytes,
|
|
73
|
+
* with optional metadata.
|
|
74
|
+
*/
|
|
75
|
+
export function renderMermaid(browser: import("puppeteer").Browser, definition: string, outputFormat: "svg" | "png" | "pdf", { viewport, backgroundColor, mermaidConfig, myCSS, pdfFit }?: ParseMDDOptions | undefined): Promise<{
|
|
76
|
+
title: string | null;
|
|
77
|
+
desc: string | null;
|
|
78
|
+
data: Buffer;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* @typedef {Object} ParseMDDOptions Options to pass to {@link parseMMD}
|
|
82
|
+
* @property {import("puppeteer").Viewport} [viewport] - Puppeteer viewport (e.g. `width`, `height`, `deviceScaleFactor`)
|
|
83
|
+
* @property {string | "transparent"} [backgroundColor] - Background color.
|
|
84
|
+
* @property {Parameters<import("mermaid")["default"]["initialize"]>[0]} [mermaidConfig] - Mermaid config.
|
|
85
|
+
* @property {CSSStyleDeclaration["cssText"]} [myCSS] - Optional CSS text.
|
|
86
|
+
* @property {boolean} [pdfFit] - If set, scale PDF to fit chart.
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Parse and render a mermaid diagram.
|
|
90
|
+
*
|
|
91
|
+
* @deprecated Prefer {@link renderMermaid}, as it also returns useful metadata.
|
|
92
|
+
*
|
|
93
|
+
* @param {import("puppeteer").Browser} browser - Puppeteer Browser
|
|
94
|
+
* @param {string} definition - Mermaid diagram definition
|
|
95
|
+
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
96
|
+
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
97
|
+
*
|
|
98
|
+
* @returns {Promise<Buffer>} The output file in bytes.
|
|
99
|
+
*/
|
|
100
|
+
export function parseMMD(browser: import("puppeteer").Browser, definition: string, outputFormat: "svg" | "png" | "pdf", opt?: ParseMDDOptions | undefined): Promise<Buffer>;
|
|
101
|
+
export function cli(): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Prints an error to stderr, then closes with exit code 1
|
|
104
|
+
*
|
|
105
|
+
* @param {string} message - The message to print to `stderr`.
|
|
106
|
+
* @returns {never} Quits Node.JS, so never returns.
|
|
107
|
+
*/
|
|
108
|
+
export function error(message: string): never;
|
|
109
|
+
import puppeteer from 'puppeteer';
|
|
110
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA4Xc,MAAM;;;;SACN,MAAM;;;;;;AAqBpB;;;;;;;;;;;;;;GAcG;AACH,2BAZW,GAAG,MAAM,IAAI,IAAI,GAAG,UAAU,EAAE,GAAG,MAAM,GAAG,SAAS,UAIrD,GAAG,MAAM,IAAI,IAAI,GAAG,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE;;;;;8BAwGlE;AAzSD;;;;;;;;;GASG;AACH,uCAPW,OAAO,WAAW,EAAE,OAAO,cAC3B,MAAM,gBACN,KAAK,GAAG,KAAK,GAAG,KAAK,8FAEnB,QAAQ;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAC,CAwJ9E;AAzLD;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,kCAPW,OAAO,WAAW,EAAE,OAAO,cAC3B,MAAM,gBACN,KAAK,GAAG,KAAK,GAAG,KAAK,sCAGnB,QAAQ,MAAM,CAAC,CAK3B;AAhHD,qCAsFC;AA9KD;;;;;GAKG;AACH,+BAHW,MAAM,GACJ,KAAK,CAKjB;sBAnBqB,WAAW"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mermaid-js/mermaid-cli",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "Command-line interface for mermaid",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "git@github.com:mermaid-js/mermaid-cli.git",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"node": "^14.13 || >=16.0"
|
|
14
14
|
},
|
|
15
15
|
"exports": "./src/index.js",
|
|
16
|
+
"types": "./dist-types/src/index.d.ts",
|
|
16
17
|
"scripts": {
|
|
17
|
-
"prepare": "vite build",
|
|
18
|
-
"prepack": "vite build",
|
|
18
|
+
"prepare": "tsc && vite build",
|
|
19
|
+
"prepack": "tsc && vite build",
|
|
19
20
|
"test": "standard && yarn node --experimental-vm-modules $(yarn bin jest)",
|
|
20
21
|
"lint": "standard",
|
|
21
22
|
"lint-fix": "standard --fix"
|
|
@@ -26,11 +27,13 @@
|
|
|
26
27
|
"puppeteer": "^19.0.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
|
-
"@fortawesome/fontawesome-free
|
|
30
|
+
"@fortawesome/fontawesome-free": "^5.6.0",
|
|
30
31
|
"@mermaid-js/mermaid-mindmap": "^9.2.2",
|
|
31
|
-
"
|
|
32
|
+
"@tsconfig/node14": "^1.0.3",
|
|
32
33
|
"jest": "^29.0.1",
|
|
34
|
+
"mermaid": "^10.0.0",
|
|
33
35
|
"standard": "^17.0.0",
|
|
36
|
+
"typescript": "^5.0.1-rc",
|
|
34
37
|
"vite": "^4.0.3",
|
|
35
38
|
"vite-plugin-singlefile": "^0.13.1",
|
|
36
39
|
"vite-svg-loader": "^4.0.0",
|
|
@@ -38,7 +41,8 @@
|
|
|
38
41
|
},
|
|
39
42
|
"files": [
|
|
40
43
|
"src/",
|
|
41
|
-
"dist/"
|
|
44
|
+
"dist/",
|
|
45
|
+
"dist-types/"
|
|
42
46
|
],
|
|
43
47
|
"jest": {
|
|
44
48
|
"moduleNameMapper": {
|
|
@@ -47,7 +51,8 @@
|
|
|
47
51
|
},
|
|
48
52
|
"standard": {
|
|
49
53
|
"ignore": [
|
|
50
|
-
"/dist/"
|
|
54
|
+
"/dist/",
|
|
55
|
+
"/dist-types/"
|
|
51
56
|
]
|
|
52
57
|
}
|
|
53
58
|
}
|
package/src/index.js
CHANGED
|
@@ -10,23 +10,48 @@ import { createRequire } from 'module'
|
|
|
10
10
|
const require = createRequire(import.meta.url)
|
|
11
11
|
const pkg = require('../package.json')
|
|
12
12
|
// __dirname is not available in ESM modules by default
|
|
13
|
-
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
13
|
+
const __dirname = url.fileURLToPath(new url.URL('.', import.meta.url))
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Prints an error to stderr, then closes with exit code 1
|
|
17
|
+
*
|
|
18
|
+
* @param {string} message - The message to print to `stderr`.
|
|
19
|
+
* @returns {never} Quits Node.JS, so never returns.
|
|
20
|
+
*/
|
|
15
21
|
const error = message => {
|
|
16
22
|
console.error(chalk.red(`\n${message}\n`))
|
|
17
23
|
process.exit(1)
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Prints a warning to stderr.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} message - The message to print to `stderr`.
|
|
30
|
+
*/
|
|
20
31
|
const warn = message => {
|
|
21
32
|
console.warn(chalk.yellow(`\n${message}\n`))
|
|
22
33
|
}
|
|
23
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Checks if the given file exists.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} file - The file to check.
|
|
39
|
+
* @returns {never | void} If the file doesn't exist, closes Node.JS with
|
|
40
|
+
* exit code 1.
|
|
41
|
+
*/
|
|
24
42
|
const checkConfigFile = file => {
|
|
25
43
|
if (!fs.existsSync(file)) {
|
|
26
44
|
error(`Configuration file "${file}" doesn't exist`)
|
|
27
45
|
}
|
|
28
46
|
}
|
|
29
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Gets the data in the given file.
|
|
50
|
+
*
|
|
51
|
+
* @param {string | undefined} inputFile - The file to read.
|
|
52
|
+
* If `undefined`, reads from `stdin` instead.
|
|
53
|
+
* @returns {Promise<string>} The contents of `inputFile` parsed as `utf8`.
|
|
54
|
+
*/
|
|
30
55
|
const getInputData = async inputFile => new Promise((resolve, reject) => {
|
|
31
56
|
// if an input file has been specified using '-i', it takes precedence over
|
|
32
57
|
// piping from stdin
|
|
@@ -42,7 +67,7 @@ const getInputData = async inputFile => new Promise((resolve, reject) => {
|
|
|
42
67
|
|
|
43
68
|
let data = ''
|
|
44
69
|
process.stdin.on('readable', function () {
|
|
45
|
-
const chunk =
|
|
70
|
+
const chunk = process.stdin.read()
|
|
46
71
|
|
|
47
72
|
if (chunk !== null) {
|
|
48
73
|
data += chunk
|
|
@@ -89,7 +114,7 @@ async function cli () {
|
|
|
89
114
|
.option('-c, --configFile [configFile]', 'JSON configuration file for mermaid.')
|
|
90
115
|
.option('-C, --cssFile [cssFile]', 'CSS file for the page.')
|
|
91
116
|
.addOption(new Option('-s, --scale [scale]', 'Puppeteer scale factor').argParser(parseCommanderInt).default(1))
|
|
92
|
-
.option('-f, --pdfFit
|
|
117
|
+
.option('-f, --pdfFit', 'Scale PDF to fit chart')
|
|
93
118
|
.option('-q, --quiet', 'Suppress log output')
|
|
94
119
|
.option('-p --puppeteerConfigFile [puppeteerConfigFile]', 'JSON configuration file for puppeteer.')
|
|
95
120
|
.parse(process.argv)
|
|
@@ -100,7 +125,7 @@ async function cli () {
|
|
|
100
125
|
|
|
101
126
|
// check input file
|
|
102
127
|
if (!input) {
|
|
103
|
-
warn('No input file
|
|
128
|
+
warn('No input file specified, reading from stdin. ' +
|
|
104
129
|
'If you want to specify an input file, please use `-i <input>.` ' +
|
|
105
130
|
'You can use `-i -` to read from stdin and to suppress this warning.'
|
|
106
131
|
)
|
|
@@ -165,11 +190,11 @@ async function cli () {
|
|
|
165
190
|
|
|
166
191
|
/**
|
|
167
192
|
* @typedef {Object} ParseMDDOptions Options to pass to {@link parseMMD}
|
|
168
|
-
* @property {puppeteer.Viewport} [viewport] - Puppeteer viewport (e.g. `width`, `height`, `deviceScaleFactor`)
|
|
193
|
+
* @property {import("puppeteer").Viewport} [viewport] - Puppeteer viewport (e.g. `width`, `height`, `deviceScaleFactor`)
|
|
169
194
|
* @property {string | "transparent"} [backgroundColor] - Background color.
|
|
170
|
-
* @property {Parameters<import("mermaid")
|
|
195
|
+
* @property {Parameters<import("mermaid")["default"]["initialize"]>[0]} [mermaidConfig] - Mermaid config.
|
|
171
196
|
* @property {CSSStyleDeclaration["cssText"]} [myCSS] - Optional CSS text.
|
|
172
|
-
* @property {boolean} pdfFit - If set, scale PDF to fit chart.
|
|
197
|
+
* @property {boolean} [pdfFit] - If set, scale PDF to fit chart.
|
|
173
198
|
*/
|
|
174
199
|
|
|
175
200
|
/**
|
|
@@ -177,26 +202,26 @@ async function cli () {
|
|
|
177
202
|
*
|
|
178
203
|
* @deprecated Prefer {@link renderMermaid}, as it also returns useful metadata.
|
|
179
204
|
*
|
|
180
|
-
* @param {puppeteer.Browser} browser - Puppeteer Browser
|
|
205
|
+
* @param {import("puppeteer").Browser} browser - Puppeteer Browser
|
|
181
206
|
* @param {string} definition - Mermaid diagram definition
|
|
182
207
|
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
183
208
|
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
184
209
|
*
|
|
185
210
|
* @returns {Promise<Buffer>} The output file in bytes.
|
|
186
211
|
*/
|
|
187
|
-
async function parseMMD (
|
|
188
|
-
const { data } = await renderMermaid(
|
|
212
|
+
async function parseMMD (browser, definition, outputFormat, opt) {
|
|
213
|
+
const { data } = await renderMermaid(browser, definition, outputFormat, opt)
|
|
189
214
|
return data
|
|
190
215
|
}
|
|
191
216
|
|
|
192
217
|
/**
|
|
193
218
|
* Render a mermaid diagram.
|
|
194
219
|
*
|
|
195
|
-
* @param {puppeteer.Browser} browser - Puppeteer Browser
|
|
220
|
+
* @param {import("puppeteer").Browser} browser - Puppeteer Browser
|
|
196
221
|
* @param {string} definition - Mermaid diagram definition
|
|
197
222
|
* @param {"svg" | "png" | "pdf"} outputFormat - Mermaid output format.
|
|
198
223
|
* @param {ParseMDDOptions} [opt] - Options, see {@link ParseMDDOptions} for details.
|
|
199
|
-
* @returns {Promise<{title
|
|
224
|
+
* @returns {Promise<{title: string | null, desc: string | null, data: Buffer}>} The output file in bytes,
|
|
200
225
|
* with optional metadata.
|
|
201
226
|
*/
|
|
202
227
|
async function renderMermaid (browser, definition, outputFormat, { viewport, backgroundColor = 'white', mermaidConfig = {}, myCSS, pdfFit } = {}) {
|
|
@@ -209,17 +234,33 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac
|
|
|
209
234
|
await page.setViewport(viewport)
|
|
210
235
|
}
|
|
211
236
|
const mermaidHTMLPath = path.join(__dirname, '..', 'dist', 'index.html')
|
|
212
|
-
await page.goto(url.pathToFileURL(mermaidHTMLPath))
|
|
237
|
+
await page.goto(url.pathToFileURL(mermaidHTMLPath).href)
|
|
213
238
|
await page.$eval('body', (body, backgroundColor) => {
|
|
214
239
|
body.style.background = backgroundColor
|
|
215
240
|
}, backgroundColor)
|
|
216
241
|
const metadata = await page.$eval('#container', async (container, definition, mermaidConfig, myCSS, backgroundColor) => {
|
|
242
|
+
/**
|
|
243
|
+
* Checks to see if the given object is one of Mermaid's DetailedErrors.
|
|
244
|
+
*
|
|
245
|
+
* @param {unknown} error - The error to check
|
|
246
|
+
* @returns {error is import("mermaid").DetailedError} Returns `true` is the `error`
|
|
247
|
+
* is a `Mermaid.DetailedError`.
|
|
248
|
+
* @see https://github.com/mermaid-js/mermaid/blob/v10.0.1/packages/mermaid/src/utils.ts#L927-L930
|
|
249
|
+
*/
|
|
250
|
+
function isDetailedError (error) {
|
|
251
|
+
return typeof error === 'object' && error !== null && 'str' in error
|
|
252
|
+
}
|
|
253
|
+
|
|
217
254
|
container.textContent = definition
|
|
218
255
|
|
|
219
|
-
/**
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
256
|
+
/**
|
|
257
|
+
* @typedef {Object} GlobalThisWithMermaid
|
|
258
|
+
* We've already imported these modules in our `index.html` file, so that they
|
|
259
|
+
* get correctly bundled.
|
|
260
|
+
* @property {import("mermaid")["default"]} mermaid Already imported mermaid instance
|
|
261
|
+
* @property {import("@mermaid-js/mermaid-mindmap")} mermaidMindmap Already imported mermaid-mindmap plugin
|
|
262
|
+
*/
|
|
263
|
+
const { mermaid, mermaidMindmap } = /** @type {GlobalThisWithMermaid & typeof globalThis} */ (globalThis)
|
|
223
264
|
|
|
224
265
|
await mermaid.registerExternalDiagrams([mermaidMindmap])
|
|
225
266
|
|
|
@@ -227,7 +268,12 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac
|
|
|
227
268
|
// should throw an error if mmd diagram is invalid
|
|
228
269
|
try {
|
|
229
270
|
await mermaid.run({
|
|
230
|
-
nodes: [
|
|
271
|
+
nodes: [
|
|
272
|
+
/**
|
|
273
|
+
* @type {HTMLElement} We know this is a `HTMLElement`, since we
|
|
274
|
+
* control the input HTML file
|
|
275
|
+
*/ (container)
|
|
276
|
+
],
|
|
231
277
|
suppressErrors: false
|
|
232
278
|
})
|
|
233
279
|
} catch (error) {
|
|
@@ -235,8 +281,10 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac
|
|
|
235
281
|
// mermaid-js doesn't currently throws JS Errors, but let's leave this
|
|
236
282
|
// here in case it does in the future
|
|
237
283
|
throw error
|
|
284
|
+
} else if (isDetailedError(error)) {
|
|
285
|
+
throw new Error(error.message)
|
|
238
286
|
} else {
|
|
239
|
-
throw new Error(
|
|
287
|
+
throw new Error(`Unknown mermaid render error: ${error}`)
|
|
240
288
|
}
|
|
241
289
|
}
|
|
242
290
|
|
|
@@ -327,13 +375,18 @@ async function renderMermaid (browser, definition, outputFormat, { viewport, bac
|
|
|
327
375
|
}
|
|
328
376
|
}
|
|
329
377
|
|
|
378
|
+
/**
|
|
379
|
+
* @typedef {object} MarkdownImageProps Markdown image properties
|
|
380
|
+
* Used to create an markdown image that looks like ``
|
|
381
|
+
* @property {string} url - Path to image.
|
|
382
|
+
* @property {string} alt - Image alt text, required.
|
|
383
|
+
* @property {string | null} [title] - Optional image title text.
|
|
384
|
+
*/
|
|
385
|
+
|
|
330
386
|
/**
|
|
331
387
|
* Creates a markdown image syntax.
|
|
332
388
|
*
|
|
333
|
-
* @param {
|
|
334
|
-
* @param {string} params.url - Path to image.
|
|
335
|
-
* @param {string} params.alt - Image alt text, required.
|
|
336
|
-
* @param {string} [params.title] - Image title text.
|
|
389
|
+
* @param {MarkdownImageProps} params - Parameters.
|
|
337
390
|
* @returns {``} The markdown image text.
|
|
338
391
|
*/
|
|
339
392
|
function markdownImage ({ url, title, alt }) {
|
|
@@ -350,19 +403,24 @@ function markdownImage ({ url, title, alt }) {
|
|
|
350
403
|
/**
|
|
351
404
|
* Renders a mermaid diagram or mermaid markdown file.
|
|
352
405
|
*
|
|
353
|
-
* @param {`${string}.${"md" | "markdown"}` | string}
|
|
406
|
+
* @param {`${string}.${"md" | "markdown"}` | string | undefined} input - If this ends with `.md`/`.markdown`,
|
|
354
407
|
* path to a markdown file containing mermaid.
|
|
355
408
|
* If this is a string, loads the mermaid definition from the given file.
|
|
356
409
|
* If this is `undefined`, loads the mermaid definition from stdin.
|
|
357
410
|
* @param {`${string}.${"md" | "markdown" | "svg" | "png" | "pdf"}`} output - Path to the output file.
|
|
358
411
|
* @param {Object} [opts] - Options
|
|
359
|
-
* @param {puppeteer.LaunchOptions} [opts.puppeteerConfig] - Puppeteer launch options.
|
|
412
|
+
* @param {import("puppeteer").LaunchOptions} [opts.puppeteerConfig] - Puppeteer launch options.
|
|
360
413
|
* @param {boolean} [opts.quiet] - If set, suppress log output.
|
|
361
414
|
* @param {"svg" | "png" | "pdf"} [opts.outputFormat] - Mermaid output format.
|
|
362
415
|
* Defaults to `output` extension. Overrides `output` extension if set.
|
|
363
416
|
* @param {ParseMDDOptions} [opts.parseMMDOptions] - Options to pass to {@link parseMMDOptions}.
|
|
364
417
|
*/
|
|
365
418
|
async function run (input, output, { puppeteerConfig = {}, quiet = false, outputFormat, parseMMDOptions } = {}) {
|
|
419
|
+
/**
|
|
420
|
+
* Logs the given message to stdout, unless `quiet` is set to `true`.
|
|
421
|
+
*
|
|
422
|
+
* @param {string} message - The message to maybe log.
|
|
423
|
+
*/
|
|
366
424
|
const info = message => {
|
|
367
425
|
if (!quiet) {
|
|
368
426
|
console.info(message)
|
|
@@ -370,32 +428,39 @@ async function run (input, output, { puppeteerConfig = {}, quiet = false, output
|
|
|
370
428
|
}
|
|
371
429
|
|
|
372
430
|
// TODO: should we use a Markdown parser like remark instead of rolling our own parser?
|
|
373
|
-
const mermaidChartsInMarkdown = /^[^\S\n]*```(?:mermaid)(\r?\n([\s\S]*?))```[^\S\n]*$/
|
|
431
|
+
const mermaidChartsInMarkdown = /^[^\S\n]*```(?:mermaid)([^\S\n]*\r?\n([\s\S]*?))```[^\S\n]*$/
|
|
374
432
|
const mermaidChartsInMarkdownRegexGlobal = new RegExp(mermaidChartsInMarkdown, 'gm')
|
|
375
433
|
const browser = await puppeteer.launch(puppeteerConfig)
|
|
376
434
|
try {
|
|
377
435
|
if (!outputFormat) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
436
|
+
const outputFormatFromFilename =
|
|
437
|
+
/**
|
|
438
|
+
* @type {"md" | "markdown" | "svg" | "png" | "pdf"}
|
|
439
|
+
*/ (path.extname(output).replace('.', ''))
|
|
440
|
+
if (outputFormatFromFilename === 'md' || outputFormatFromFilename === 'markdown') {
|
|
441
|
+
// fallback to svg in case no outputFormat is given and output file is MD
|
|
442
|
+
outputFormat = 'svg'
|
|
443
|
+
} else {
|
|
444
|
+
outputFormat = outputFormatFromFilename
|
|
445
|
+
}
|
|
383
446
|
}
|
|
384
447
|
if (!/(?:svg|png|pdf)$/.test(outputFormat)) {
|
|
385
448
|
throw new Error('Output format must be one of "svg", "png" or "pdf"')
|
|
386
449
|
}
|
|
387
450
|
|
|
388
451
|
const definition = await getInputData(input)
|
|
389
|
-
if (/\.(md|markdown)$/.test(input)) {
|
|
452
|
+
if (input && /\.(md|markdown)$/.test(input)) {
|
|
390
453
|
const imagePromises = []
|
|
391
454
|
for (const mermaidCodeblockMatch of definition.matchAll(mermaidChartsInMarkdownRegexGlobal)) {
|
|
392
455
|
const mermaidDefinition = mermaidCodeblockMatch[1]
|
|
393
456
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
457
|
+
/** Output can be either a template image file, or a `.md` output file.
|
|
458
|
+
* If it is a template image file, use that to created numbered diagrams
|
|
459
|
+
* I.e. if "out.png", use "out-1.png", "out-2.png", etc
|
|
460
|
+
* If it is an output `.md` file, use that to base .svg numbered diagrams on
|
|
461
|
+
* I.e. if "out.md". use "out-1.svg", "out-2.svg", etc
|
|
462
|
+
* @type {string}
|
|
463
|
+
*/
|
|
399
464
|
const outputFile = output.replace(
|
|
400
465
|
/(\.(md|markdown|png|svg|pdf))$/,
|
|
401
466
|
`-${imagePromises.length + 1}$1`
|
|
@@ -427,7 +492,12 @@ async function run (input, output, { puppeteerConfig = {}, quiet = false, output
|
|
|
427
492
|
if (/\.(md|markdown)$/.test(output)) {
|
|
428
493
|
const outDefinition = definition.replace(mermaidChartsInMarkdownRegexGlobal, (_mermaidMd) => {
|
|
429
494
|
// pop first image from front of array
|
|
430
|
-
const { url, title, alt } =
|
|
495
|
+
const { url, title, alt } =
|
|
496
|
+
/**
|
|
497
|
+
* @type {MarkdownImageProps} We use the same regex,
|
|
498
|
+
* so we will never try to get too many objects from the array.
|
|
499
|
+
* (aka `images.shift()` will never return `undefined`)
|
|
500
|
+
*/ (images.shift())
|
|
431
501
|
return markdownImage({ url, title, alt: alt || 'diagram' })
|
|
432
502
|
})
|
|
433
503
|
await fs.promises.writeFile(output, outDefinition, 'utf-8')
|