-
Notifications
You must be signed in to change notification settings - Fork 22
/
index.js
106 lines (86 loc) · 2.94 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { parseComponent } from '@vuedoc/parser';
import { render, Event } from './lib/Markdown.js';
import merge from 'deepmerge';
import JsonSchemav from 'jsonschemav';
import ValidationError from 'jsonschemav/lib/error.js';
import schema from './lib/config.schema.js';
const jsv = new JsonSchemav();
const validator = jsv.compile(schema);
function renderFile(filename, keepStreamOpen, { ...options }) {
return ({ warnings = [], ...component }) => new Promise((resolve, reject) => {
warnings.forEach((message) => process.stderr.write(`Warn: ${message}\n`));
const renderer = render(component, options);
const stream = typeof options.stream === 'function' && filename
? options.stream(filename)
: options.stream;
if (component.errors.length) {
component.errors.forEach((message) => process.stderr.write(`Err: ${message}\n`));
reject(new Error(component.errors[0]));
return;
}
if (stream) {
renderer.emiter
.on(Event.write, (text) => stream.write(text))
.on(Event.end, () => {
if (!keepStreamOpen) {
stream.end();
}
resolve();
});
} else {
let document = '';
renderer.emiter
.on(Event.write, (text) => {
document += text;
})
.on(Event.end, () => resolve(document.trim() + '\n'));
}
renderer.start();
});
}
export async function renderMarkdown({ stream, filename, reduce = true, ...options }) {
if (!options.parsing) {
options.parsing = {};
}
// compatibility with previous versions
if (filename && !options.filenames) {
options.filenames = [filename];
}
try {
const instance = await validator;
const { parsing: parsingOptions, join, filenames, ...restOptions } = await instance.validate(options);
const output = await new Promise((resolve, reject) => {
const renderOptions = { stream, ...restOptions };
if (filenames.length) {
const parsers = filenames.map((filename) => parseComponent({ ...parsingOptions, filename }));
let promises = [];
if (join) {
promises = [
Promise.all(parsers).then(merge.all).then(renderFile(null, false, renderOptions)),
];
} else {
promises = parsers.map((promise, index) => {
return promise.then(renderFile(filenames[index], index !== filenames.length - 1, renderOptions));
});
}
resolve(promises);
} else if (parsingOptions.filecontent) {
resolve([
parseComponent(parsingOptions).then(renderFile(null, false, renderOptions)),
]);
} else {
reject(new Error('Invalid options. Missing options.filenames'));
}
});
const docs = await Promise.all(output);
if (reduce && docs.length === 1) {
return docs[0];
}
return docs;
} catch (err) {
if (err instanceof ValidationError) {
err.message = 'Invalid options';
}
throw err;
}
}