forked from SNCFdevelopers/wcs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.js
137 lines (125 loc) · 4.48 KB
/
build.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* This is a custom build script used to separate html files
* per component and integrate them to the index.html
*/
const fs = require('fs');
const chokidar = require('chokidar');
const process = require('process');
const mem = require('mem');
const hljs = require('highlight.js');
const html = require('highlight.js/lib/languages/htmlbars');
hljs.registerLanguage('language-html', html);
const md = require('markdown-it')({
html: true,
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value;
} catch (__) {
}
}
return ''; // use external default escaping
}
});
const render = mem(content => md.render(content))
/**
* @returns {Promise<string[]>} All the file names with the given extension
* @param {import("fs").PathLike} basePath
* @param {string} extension
* @param {string} filter
*/
async function allFilesWithExtension(basePath, extension, filter) {
let filesByDir = await Promise.all((await fs.promises.readdir(basePath))
.map(async name => {
const file = await fs.promises.stat(basePath + name);
if (name[0] === '.') {
return [];
}
return file.isDirectory()
? await allFilesWithExtension(basePath + name + '/', extension, filter)
: name.endsWith(extension)
? [basePath + name]
: [];
}));
filesByDir = filesByDir.reduce((curr, acc) => [...acc, ...curr], []);
if (filter != null) {
filesByDir = filesByDir.filter(x => {
return x.includes('/' + filter + '/');
});
}
return filesByDir;
}
function insertAfter(string, tag, insertSubString) {
const insertIndex = getInsertIndex(string, tag);
return string.slice(0, insertIndex) + insertSubString + string.slice(insertIndex);
}
function getInsertIndex(fileContent, tag) {
return fileContent.indexOf(tag) + tag.length;
}
/**
*
* @param {string[]} filesPath
*/
async function updateIndex(filesPath) {
const start = process.hrtime();
console.log('Updating files...');
const examplesP = await Promise.all(filesPath.map(async path => {
const readme = (await fs.promises.readFile(path.replace('example.html', 'readme.md'))).toString();
const readmeHTML = render(readme.replace(/```html([\S\s]*?)```/gmu, '```html$1```\n$1'));
const name = readmeHTML.match(/<h1>(.*)<\/h1>/)[1];
const [doc, api] = readmeHTML.split('<!-- Auto Generated Below -->');
const examples = doc.replace(/<h1>(.*)<\/h1>/, '').trim();
if (examples.length < 30) {
console.log(`Generating none for ${name}, examples are empty`);
return '';
}
return `
<h1>${name}</h1>
<wcs-card>
<wcs-tabs>
<wcs-tab header="Examples" class="normal-padding">
${examples}
</wcs-tab>
<wcs-tab header="API" class="normal-padding">
${api}
</wcs-tab>
</wcs-tabs>
</wcs-card>`;
}));
const examples = examplesP.reduce((acc, cur) => acc + cur + '\r\n', '');
const index = (await fs.promises.readFile('./src/template.html')).toString();
const newContent = insertAfter(index, '<!--Import-->', examples);
await fs.promises.writeFile('./src/index.html', newContent);
// Logging
const end = process.hrtime(start);
console.log('Rewrite finished in: %d %dms', end[0], end[1] / 100000);
}
/**
* return null if no filter are specifies in arguments
*/
function getFilterComponentName() {
let filterComponentName = null;
for (let i = 0; i < process.argv.length; i++) {
if (process.argv[i] == "--filter") {
filterComponentName = process.argv[i + 1];
}
}
return filterComponentName;
}
async function watchBuild() {
let filterComponentArgument = getFilterComponentName();
const files = await allFilesWithExtension('./src/components/', '.md', filterComponentArgument);
console.log('Watching files:');
files.sort().forEach(f => console.log(' - ' + f));
const watcher = chokidar.watch([
...files.sort(),
'src/template.html'
]);
watcher.on('ready', () => updateIndex(files));
watcher.on('change', () => updateIndex(files));
if (process.argv[2] !== '--watch') {
watcher.close();
updateIndex(files);
}
}
watchBuild();