vuepress-jsdoc 4.3.1 → 6.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/index.js CHANGED
@@ -1,81 +1,3 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- var __read = (this && this.__read) || function (o, n) {
39
- var m = typeof Symbol === "function" && o[Symbol.iterator];
40
- if (!m) return o;
41
- var i = m.call(o), r, ar = [], e;
42
- try {
43
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
44
- }
45
- catch (error) { e = { error: error }; }
46
- finally {
47
- try {
48
- if (r && !r.done && (m = i["return"])) m.call(i);
49
- }
50
- finally { if (e) throw e.error; }
51
- }
52
- return ar;
53
- };
54
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
55
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56
- if (ar || !(i in from)) {
57
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
58
- ar[i] = from[i];
59
- }
60
- }
61
- return to.concat(ar || Array.prototype.slice.call(from));
62
- };
63
- var __values = (this && this.__values) || function(o) {
64
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
65
- if (m) return m.call(o);
66
- if (o && typeof o.length === "number") return {
67
- next: function () {
68
- if (o && i >= o.length) o = void 0;
69
- return { value: o && o[i++], done: !o };
70
- }
71
- };
72
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
73
- };
74
- var __importDefault = (this && this.__importDefault) || function (mod) {
75
- return (mod && mod.__esModule) ? mod : { "default": mod };
76
- };
77
- Object.defineProperty(exports, "__esModule", { value: true });
78
- exports.generate = void 0;
79
1
  /*
80
2
  * @vuepress
81
3
  * ---
@@ -83,309 +5,244 @@ exports.generate = void 0;
83
5
  * headline: The Main File
84
6
  * ---
85
7
  */
86
- var chalk_1 = __importDefault(require("chalk"));
87
- var chokidar_1 = __importDefault(require("chokidar"));
88
- var del_1 = __importDefault(require("del"));
89
- var promises_1 = __importDefault(require("fs/promises"));
90
- var mkdirp_1 = __importDefault(require("mkdirp"));
91
- var readline_1 = __importDefault(require("readline"));
92
- var constants_1 = require("./constants");
93
- var list_folder_1 = require("./lib/list-folder");
94
- var parser_1 = require("./lib/parser");
95
- var vue_sidebar_1 = require("./lib/vue-sidebar");
8
+ import chokidar from 'chokidar';
9
+ import { deleteAsync } from 'del';
10
+ import kleur from 'kleur';
11
+ import fs from 'node:fs/promises';
12
+ import os from 'node:os';
13
+ import path from 'node:path';
14
+ import { StatisticType } from './constants.js';
15
+ import { getPageName, listFolder, normalizePath } from './lib/list-folder.js';
16
+ import { getDestFolder, parseFile, writeContentToFile } from './lib/parser.js';
17
+ import { createSidebarConfig } from './lib/vue-sidebar.js';
18
+ export { listFolder } from './lib/list-folder.js';
19
+ export { parseFile, writeContentToFile } from './lib/parser.js';
20
+ export { createSidebarConfig, generateVitepressSidebar, generateVueSidebar } from './lib/vue-sidebar.js';
21
+ export { parseComment, parseVuepressFileHeader } from './lib/comment-parser.js';
22
+ export { defineConfig, loadConfig } from './lib/config.js';
23
+ export { vuepressJsdocPlugin } from './lib/vuepress-plugin.js';
24
+ export { StatisticType } from './constants.js';
96
25
  /**
97
- * Create the sidebar
98
- * @param {object} options
99
- * @returns {Promise}
26
+ * Split a comma separated string or a list of strings into a list
27
+ * @param {string|string[]} value
28
+ * @returns {string[]}
100
29
  */
101
- var createVuepressSidebar = function (options) {
102
- return promises_1.default.writeFile("".concat(options.docsFolder, "/config.js"), "exports.fileTree=".concat(JSON.stringify(options.fileTree), ";exports.sidebarTree = (title = 'Mainpage') => (").concat(JSON.stringify((0, vue_sidebar_1.generateVueSidebar)(options)).replace('::vuepress-jsdoc-title::', '"+title+"'), ");"));
103
- };
30
+ const toList = (value) => (Array.isArray(value) ? value : (value || '').split(','))
31
+ .flatMap((v) => v.split(','))
32
+ .map((v) => v.trim())
33
+ .filter(Boolean);
104
34
  /**
105
- * Parse file
106
- * @param {DirectoryFile} file
35
+ * Parse all CLI arguments
107
36
  * @param {CLIArguments} argv
108
- * @returns {Promise}
37
+ * @returns {object} all arguments
109
38
  */
110
- var parseDirectoryFile = function (file, argv) {
111
- var _a = parseArguments(argv), srcFolder = _a.srcFolder, docsFolder = _a.docsFolder, partials = _a.partials;
112
- if (!file.isDir && file.folder) {
113
- if (['.jsx', '.tsx', '.ts', '.js'].includes(file.ext || '')) {
114
- return (0, parser_1.parseFile)(file, srcFolder, docsFolder, argv.jsDocConfigPath, partials);
115
- }
116
- if (file.ext === '.vue') {
117
- return (0, parser_1.parseVueFile)(file, srcFolder, docsFolder);
118
- }
119
- }
39
+ export const parseArguments = (argv) => {
40
+ const codeFolder = normalizePath(argv.folder || 'code');
41
+ const dist = normalizePath(argv.dist || './documentation');
42
+ const srcFolder = normalizePath(argv.source || './src');
43
+ return {
44
+ include: toList(argv.include),
45
+ exclude: toList(argv.exclude),
46
+ srcFolder,
47
+ codeFolder,
48
+ docsFolder: path.posix.join(dist, codeFolder),
49
+ title: argv.title || 'API',
50
+ readme: argv.readme,
51
+ readmePath: argv.readme || path.join(srcFolder, 'README.md'),
52
+ rmPattern: toList(argv.rmPattern),
53
+ partials: toList(argv.partials),
54
+ jsDocConfigPath: argv.jsDocConfigPath,
55
+ collapsible: Boolean(argv.collapsible),
56
+ format: argv.format === 'vitepress' ? 'vitepress' : 'vuepress'
57
+ };
120
58
  };
121
59
  /**
122
- * Create the readme file. First page when entering the documentation.
123
- * @param {CLIArguments} argv
124
- * @param {string} deletedPaths
125
- * @returns {void}
60
+ * Run async tasks with a limited concurrency, because every jsdoc call spawns a child process.
61
+ * @param {T[]} items
62
+ * @param {Function} fn
63
+ * @returns {Promise<R[]>} results in the order of the items
126
64
  */
127
- var createReadmeFile = function (argv, deletedPaths) { return __awaiter(void 0, void 0, void 0, function () {
128
- var _a, srcFolder, codeFolder, docsFolder, title, readme, readMeContent, readmePath, e_1;
129
- return __generator(this, function (_b) {
130
- switch (_b.label) {
131
- case 0:
132
- _a = parseArguments(argv), srcFolder = _a.srcFolder, codeFolder = _a.codeFolder, docsFolder = _a.docsFolder, title = _a.title, readme = _a.readme;
133
- readMeContent = "### Welcome to ".concat(title);
134
- readmePath = readme || "".concat(srcFolder, "/README.md");
135
- _b.label = 1;
136
- case 1:
137
- _b.trys.push([1, 3, , 4]);
138
- return [4 /*yield*/, promises_1.default.readFile(readmePath, 'utf-8')];
139
- case 2:
140
- readMeContent = _b.sent();
141
- if (deletedPaths === null || deletedPaths === void 0 ? void 0 : deletedPaths.some(function (p) { return p.indexOf("".concat(codeFolder, "/README.md")) !== -1; })) {
142
- console.log("\n".concat(chalk_1.default.white.bgBlack(' README '), " ").concat(chalk_1.default.dim(readmePath.replace('README.md', ''))).concat(chalk_1.default.bold('README.md'), " \u2192 ").concat(chalk_1.default.dim(docsFolder)).concat(chalk_1.default.bold('/README.md')));
143
- }
144
- return [3 /*break*/, 4];
145
- case 3:
146
- e_1 = _b.sent();
147
- console.log("\n".concat(chalk_1.default.white.bgBlack(' README '), " Add default README.md"));
148
- return [3 /*break*/, 4];
149
- case 4: return [4 /*yield*/, promises_1.default.writeFile("".concat(docsFolder, "/README.md"), readMeContent)];
150
- case 5:
151
- _b.sent();
152
- return [2 /*return*/];
65
+ const mapLimit = async (items, fn, limit = os.availableParallelism()) => {
66
+ const results = new Array(items.length);
67
+ let index = 0;
68
+ const worker = async () => {
69
+ while (index < items.length) {
70
+ const i = index++;
71
+ results[i] = await fn(items[i]);
153
72
  }
154
- });
155
- }); };
73
+ };
74
+ await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));
75
+ return results;
76
+ };
156
77
  /**
157
- * Parse all CLI arguments
158
- * @param {CLIArguments} argv
159
- * @returns {object} all arguments
78
+ * Get the sidebar options of the given file tree
79
+ * @param {Options} options
80
+ * @param {FileTree[]} fileTree created by `listFolder`
81
+ * @returns {SidebarOptions}
160
82
  */
161
- var parseArguments = function (argv) {
162
- return {
163
- include: (argv.include || '').split(',').filter(Boolean),
164
- exclude: (argv.exclude || '').split(',').filter(Boolean),
165
- srcFolder: argv.source.replace('./', ''),
166
- codeFolder: argv.folder,
167
- docsFolder: "".concat(argv.dist, "/").concat(argv.folder),
168
- title: argv.title,
169
- readme: argv.readme,
170
- rmPattern: argv.rmPattern || [],
171
- partials: argv.partials || []
83
+ export const getSidebarOptions = (options, fileTree) => ({
84
+ fileTree,
85
+ srcFolder: options.srcFolder,
86
+ docsFolder: options.docsFolder,
87
+ codeFolder: options.codeFolder,
88
+ title: options.title,
89
+ format: options.format,
90
+ collapsible: options.collapsible
91
+ });
92
+ /**
93
+ * Write the config.js with the file tree and sidebar
94
+ * @param {Options} options
95
+ * @param {FileTree[]} fileTree created by `listFolder`
96
+ * @returns {Promise<void>}
97
+ */
98
+ const createVuepressSidebar = (options, fileTree) => fs.writeFile(path.join(options.docsFolder, 'config.js'), createSidebarConfig(getSidebarOptions(options, fileTree)));
99
+ /**
100
+ * Parse a file and write the markdown file
101
+ * @param {DirectoryFile} file
102
+ * @param {Options} options
103
+ * @returns {Promise<ParseReturn>}
104
+ */
105
+ const processFile = async (file, options) => {
106
+ const parseOptions = {
107
+ srcFolder: options.srcFolder,
108
+ destFolder: options.docsFolder,
109
+ jsDocConfigPath: options.jsDocConfigPath,
110
+ partials: options.partials
172
111
  };
112
+ const result = await parseFile(file, parseOptions);
113
+ await writeContentToFile(result);
114
+ return result;
173
115
  };
174
116
  /**
175
- * Default command that generate md files
176
- * @param {object} argv passed arguments
117
+ * Create the readme file. First page when entering the documentation.
118
+ * @param {Options} options
119
+ * @returns {Promise<void>}
177
120
  */
178
- var generate = function (argv) { return __awaiter(void 0, void 0, void 0, function () {
179
- var _a, exclude, include, srcFolder, codeFolder, docsFolder, title, rmPattern, startTime, deletedPaths, lsFolder, parsePromises, _b, _c, file, e_2_1, _loop_1, _d, _e, file, result, _f, _g, file, _h, _j, entry, color, resultTime;
180
- var e_2, _k, e_3, _l, e_4, _m, e_5, _o, _p;
181
- return __generator(this, function (_q) {
182
- switch (_q.label) {
183
- case 0:
184
- _a = parseArguments(argv), exclude = _a.exclude, include = _a.include, srcFolder = _a.srcFolder, codeFolder = _a.codeFolder, docsFolder = _a.docsFolder, title = _a.title, rmPattern = _a.rmPattern;
185
- startTime = +new Date();
186
- return [4 /*yield*/, (0, del_1.default)(__spreadArray(["".concat(docsFolder, "/**/*")], __read(rmPattern), false))];
187
- case 1:
188
- deletedPaths = _q.sent();
189
- return [4 /*yield*/, (0, list_folder_1.listFolder)(srcFolder, exclude, include)];
190
- case 2:
191
- lsFolder = _q.sent();
192
- return [4 /*yield*/, (0, mkdirp_1.default)(docsFolder)];
193
- case 3:
194
- _q.sent();
195
- parsePromises = [];
196
- _q.label = 4;
197
- case 4:
198
- _q.trys.push([4, 9, 10, 11]);
199
- _b = __values(lsFolder.paths), _c = _b.next();
200
- _q.label = 5;
201
- case 5:
202
- if (!!_c.done) return [3 /*break*/, 8];
203
- file = _c.value;
204
- if (!!file.isDir) return [3 /*break*/, 7];
205
- readline_1.default.clearLine(process.stdout, 0);
206
- readline_1.default.cursorTo(process.stdout, 0);
207
- process.stdout.write(chalk_1.default.dim(" ".concat(file.path, " ")));
208
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 20); })];
209
- case 6:
210
- _q.sent();
211
- _q.label = 7;
212
- case 7:
213
- _c = _b.next();
214
- return [3 /*break*/, 5];
215
- case 8: return [3 /*break*/, 11];
216
- case 9:
217
- e_2_1 = _q.sent();
218
- e_2 = { error: e_2_1 };
219
- return [3 /*break*/, 11];
220
- case 10:
221
- try {
222
- if (_c && !_c.done && (_k = _b.return)) _k.call(_b);
223
- }
224
- finally { if (e_2) throw e_2.error; }
225
- return [7 /*endfinally*/];
226
- case 11:
227
- readline_1.default.clearLine(process.stdout, 0);
228
- readline_1.default.cursorTo(process.stdout, 0);
229
- _loop_1 = function (file) {
230
- parsePromises.push((function () { return __awaiter(void 0, void 0, void 0, function () {
231
- var data;
232
- return __generator(this, function (_a) {
233
- switch (_a.label) {
234
- case 0: return [4 /*yield*/, parseDirectoryFile(file, argv)];
235
- case 1:
236
- data = _a.sent();
237
- if (data && (data === null || data === void 0 ? void 0 : data.relativePathDest)) {
238
- return [2 /*return*/, (0, parser_1.writeContentToFile)(data, data.relativePathDest)];
239
- }
240
- return [2 /*return*/];
241
- }
242
- });
243
- }); })());
244
- };
245
- try {
246
- // iterate through files and parse them
247
- for (_d = __values(lsFolder.paths), _e = _d.next(); !_e.done; _e = _d.next()) {
248
- file = _e.value;
249
- _loop_1(file);
250
- }
251
- }
252
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
253
- finally {
254
- try {
255
- if (_e && !_e.done && (_l = _d.return)) _l.call(_d);
256
- }
257
- finally { if (e_3) throw e_3.error; }
258
- }
259
- return [4 /*yield*/, Promise.all(parsePromises)];
260
- case 12:
261
- result = _q.sent();
262
- result = result.filter(Boolean);
263
- // write vuepress sidebar
264
- return [4 /*yield*/, createVuepressSidebar({
265
- fileTree: lsFolder.tree,
266
- srcFolder: srcFolder,
267
- docsFolder: docsFolder,
268
- codeFolder: codeFolder,
269
- title: title
270
- })];
271
- case 13:
272
- // write vuepress sidebar
273
- _q.sent();
274
- try {
275
- // print stats
276
- for (_f = __values(lsFolder.excluded), _g = _f.next(); !_g.done; _g = _f.next()) {
277
- file = _g.value;
278
- console.log(chalk_1.default.reset.inverse.bold.blue(' EXCLUDE '), "".concat(chalk_1.default.dim(file.folder)).concat(chalk_1.default.bold(file.name + file.ext)));
279
- }
280
- }
281
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
282
- finally {
283
- try {
284
- if (_g && !_g.done && (_m = _f.return)) _m.call(_f);
285
- }
286
- finally { if (e_4) throw e_4.error; }
287
- }
288
- console.log();
289
- try {
290
- for (_h = __values(result.flat()), _j = _h.next(); !_j.done; _j = _h.next()) {
291
- entry = _j.value;
292
- if (!entry.file)
293
- continue;
294
- color = (_p = {},
295
- _p[constants_1.StatisticType.INCLUDE] = 'green',
296
- _p[constants_1.StatisticType.ERROR] = 'red',
297
- _p[constants_1.StatisticType.EMPTY] = 'yellow',
298
- _p[constants_1.StatisticType.EXCLUDE] = 'blue',
299
- _p)[entry.type];
300
- console.log(chalk_1.default.reset.inverse.bold[color](" ".concat(entry.type, " ")), "".concat(chalk_1.default.dim(entry.relativePathSrc)).concat(chalk_1.default.bold(entry.file.name + entry.file.ext), " \u2192 ").concat(chalk_1.default.dim(entry.relativePathDest)).concat(chalk_1.default.bold(entry.file.name + '.md')));
301
- }
302
- }
303
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
304
- finally {
305
- try {
306
- if (_j && !_j.done && (_o = _h.return)) _o.call(_h);
307
- }
308
- finally { if (e_5) throw e_5.error; }
309
- }
310
- // create README.md
311
- return [4 /*yield*/, createReadmeFile(argv, deletedPaths)];
312
- case 14:
313
- // create README.md
314
- _q.sent();
315
- resultTime = (Math.abs(startTime - +new Date()) / 1000).toFixed(2);
316
- console.log("\n\u23F0 Time: ".concat(resultTime, "s"));
317
- watchFiles(argv);
318
- return [2 /*return*/];
121
+ const createReadmeFile = async (options) => {
122
+ const { readmePath } = options;
123
+ // vitepress uses index.md as the page of a folder
124
+ const target = options.format === 'vitepress' ? 'index.md' : 'README.md';
125
+ let content = `# ${options.title}\n`;
126
+ try {
127
+ content = await fs.readFile(readmePath, 'utf-8');
128
+ console.log(`${kleur.white().bgBlack(' README ')} ${kleur.dim(readmePath)} → ${kleur.dim(options.docsFolder)}/${target}`);
129
+ }
130
+ catch {
131
+ console.log(`${kleur.white().bgBlack(' README ')} no README.md found, a default one was created`);
132
+ }
133
+ await fs.writeFile(path.join(options.docsFolder, target), content);
134
+ };
135
+ const STATUS_COLORS = {
136
+ [StatisticType.INCLUDE]: kleur.green,
137
+ [StatisticType.ERROR]: kleur.red,
138
+ [StatisticType.EMPTY]: kleur.yellow,
139
+ [StatisticType.EXCLUDE]: kleur.blue
140
+ };
141
+ /**
142
+ * Print a status line
143
+ * @param {StatisticType} type
144
+ * @param {string} message
145
+ */
146
+ const printStatus = (type, message) => {
147
+ console.log(STATUS_COLORS[type]()
148
+ .inverse()
149
+ .bold(` ${type.padEnd(7)} `), message);
150
+ };
151
+ /**
152
+ * Print the result of a parsed file
153
+ * @param {ParseReturn} entry
154
+ */
155
+ const printResult = (entry) => {
156
+ const source = `${kleur.dim(entry.file.folder)}${kleur.bold(path.basename(entry.file.path))}`;
157
+ if (entry.type === StatisticType.INCLUDE) {
158
+ printStatus(entry.type, `${source} → ${kleur.dim(entry.dest + '/')}${kleur.bold(entry.file.name + '.md')}`);
159
+ }
160
+ else if (entry.type === StatisticType.EMPTY) {
161
+ printStatus(entry.type, `${source} ${kleur.dim('(no documentation found)')}`);
162
+ }
163
+ else {
164
+ printStatus(entry.type, source);
165
+ if (entry.error) {
166
+ console.log(kleur.red(entry.error.replace(/^/gm, ' ')));
319
167
  }
320
- });
321
- }); };
322
- exports.generate = generate;
168
+ }
169
+ };
323
170
  /**
324
- * Watch files in source folder
325
- * @param {CLIArguments} argv
171
+ * Default command that generates the markdown files
172
+ * @param {CLIArguments} argv passed arguments
173
+ * @returns {Promise<ParseReturn[]>} results of all parsed files
326
174
  */
327
- var watchFiles = function (argv) {
328
- var _a = parseArguments(argv), exclude = _a.exclude, include = _a.include, srcFolder = _a.srcFolder, codeFolder = _a.codeFolder, docsFolder = _a.docsFolder, title = _a.title;
175
+ export const generate = async (argv) => {
176
+ const options = parseArguments(argv);
177
+ const startTime = performance.now();
178
+ // the generated folder is always recreated
179
+ await fs.rm(options.docsFolder, { recursive: true, force: true });
180
+ if (options.rmPattern.length) {
181
+ await deleteAsync(options.rmPattern);
182
+ }
183
+ await fs.mkdir(options.docsFolder, { recursive: true });
184
+ const lsFolder = await listFolder(options.srcFolder, options.exclude, options.include);
185
+ for (const file of lsFolder.excluded) {
186
+ printStatus(StatisticType.EXCLUDE, `${kleur.dim(file.folder)}${kleur.bold(path.basename(file.path))}`);
187
+ }
188
+ const results = await mapLimit(lsFolder.paths, async (file) => {
189
+ const result = await processFile(file, options);
190
+ printResult(result);
191
+ return result;
192
+ });
193
+ await Promise.all([createVuepressSidebar(options, lsFolder.tree), createReadmeFile(options)]);
194
+ const count = (type) => results.filter((r) => r.type === type).length;
195
+ const resultTime = ((performance.now() - startTime) / 1000).toFixed(2);
196
+ console.log(`\n${kleur.green(`${count(StatisticType.INCLUDE)} generated`)}, ${kleur.yellow(`${count(StatisticType.EMPTY)} empty`)}, ${kleur.red(`${count(StatisticType.ERROR)} failed`)}, ${kleur.blue(`${lsFolder.excluded.length} excluded`)}`);
197
+ console.log(`ā° Time: ${resultTime}s`);
329
198
  if (argv.watch) {
330
- console.log('\n---\n\nšŸ‘€ watching files...');
331
- var watcher = chokidar_1.default.watch([srcFolder, argv.readme, "".concat(srcFolder, "/README.md")].filter(Boolean), {
332
- ignored: /(^|[\/\\])\../,
333
- persistent: true
334
- });
335
- watcher.on('change', function (path) { return __awaiter(void 0, void 0, void 0, function () {
336
- var lsFolder, file;
337
- var _a;
338
- return __generator(this, function (_b) {
339
- switch (_b.label) {
340
- case 0: return [4 /*yield*/, (0, list_folder_1.listFolder)(srcFolder, exclude, include)];
341
- case 1:
342
- lsFolder = _b.sent();
343
- file = lsFolder.paths.find(function (p) { return p.path === path; });
344
- readline_1.default.clearLine(process.stdout, 0);
345
- readline_1.default.cursorTo(process.stdout, 0);
346
- if (!(path === 'README.md' || path === "".concat(srcFolder, "/README.md"))) return [3 /*break*/, 3];
347
- return [4 /*yield*/, createReadmeFile(argv)];
348
- case 2:
349
- _b.sent();
350
- _b.label = 3;
351
- case 3:
352
- if (file) {
353
- process.stdout.write(chalk_1.default.dim("update ".concat(file.name + file.ext)));
354
- (_a = parseDirectoryFile(file, argv)) === null || _a === void 0 ? void 0 : _a.then(function (data) {
355
- if (data) {
356
- (0, parser_1.writeContentToFile)(data, data.relativePathDest);
357
- }
358
- createVuepressSidebar({
359
- fileTree: lsFolder.tree,
360
- srcFolder: srcFolder,
361
- docsFolder: docsFolder,
362
- codeFolder: codeFolder,
363
- title: title
364
- });
365
- });
366
- }
367
- return [2 /*return*/];
368
- }
369
- });
370
- }); });
199
+ watchFiles(argv);
371
200
  }
201
+ return results;
372
202
  };
373
203
  /**
374
- * The vuepress plugins
204
+ * Watch files in source folder and update the generated markdown files
375
205
  * @param {CLIArguments} argv
376
- * @param {object} ctx
377
- * @returns {object}
206
+ * @returns {object} chokidar watcher
378
207
  */
379
- var plugin = function (argv, ctx) { return ({
380
- name: 'vuepress-plugin-jsdoc',
381
- ready: function () { return __awaiter(void 0, void 0, void 0, function () {
382
- return __generator(this, function (_a) {
383
- if (!ctx.isProd) {
384
- argv.watch = true;
385
- watchFiles(argv);
208
+ export const watchFiles = (argv) => {
209
+ const options = parseArguments(argv);
210
+ const readmePath = path.resolve(options.readmePath);
211
+ console.log('\n---\n\nšŸ‘€ watching files...');
212
+ const watcher = chokidar.watch([options.srcFolder, options.readme].filter((p) => Boolean(p)), {
213
+ ignored: (p) => /(^|[/\\])\.[^/\\]/.test(p) || p.includes('node_modules'),
214
+ ignoreInitial: true
215
+ });
216
+ let queue = Promise.resolve();
217
+ const update = (event, changedPath) => {
218
+ queue = queue.then(async () => {
219
+ try {
220
+ if (path.resolve(changedPath) === readmePath) {
221
+ await createReadmeFile(options);
222
+ return;
223
+ }
224
+ const { paths, tree } = await listFolder(options.srcFolder, options.exclude, options.include);
225
+ const file = paths.find((p) => path.resolve(p.path) === path.resolve(changedPath));
226
+ if (event === 'unlink') {
227
+ const dir = normalizePath(path.dirname(changedPath));
228
+ const name = getPageName(dir, path.basename(changedPath, path.extname(changedPath)));
229
+ const dest = getDestFolder({ folder: dir }, options.srcFolder, options.docsFolder);
230
+ await fs.rm(path.join(dest, `${name}.md`), { force: true });
231
+ console.log(kleur.dim(`removed ${changedPath}`));
232
+ }
233
+ else if (file) {
234
+ printResult(await processFile(file, options));
235
+ }
236
+ await createVuepressSidebar(options, tree);
237
+ }
238
+ catch (e) {
239
+ console.error(e);
386
240
  }
387
- return [2 /*return*/];
388
241
  });
389
- }); }
390
- }); };
391
- exports.default = plugin;
242
+ };
243
+ watcher.on('all', (event, p) => {
244
+ if (event === 'add' || event === 'change' || event === 'unlink')
245
+ update(event, p);
246
+ });
247
+ return watcher;
248
+ };