documentation
Version:
a documentation generator
102 lines (91 loc) • 2.63 kB
JavaScript
/* @flow */
const errorPage = require('../serve/error_page');
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const sharedOptions = require('./shared_options');
const Server = require('../serve/server');
const _ = require('lodash');
const getPort = require('get-port');
const documentation = require('../');
module.exports.command = 'serve [input..]';
module.exports.description = 'generate, update, and display HTML documentation';
/**
* Add yargs parsing for the serve command
* @param {Object} yargs module instance
* @returns {Object} yargs with options
* @private
*/
module.exports.builder = Object.assign(
{},
sharedOptions.sharedOutputOptions,
sharedOptions.sharedInputOptions,
{
port: {
describe: 'preferred port for the local server',
type: 'number',
default: 4001
}
}
);
/**
* Wrap the documentation build command along with a server, making it possible
* to preview changes live
* @private
* @param {Object} argv cli input
* @returns {undefined} has side effects
*/
module.exports.handler = function serve(argv: Object) {
argv._handled = true;
if (!argv.input.length) {
try {
argv.input = [
JSON.parse(fs.readFileSync(path.resolve('package.json'), 'utf8'))
.main || 'index.js'
];
} catch (e) {
throw new Error(
'documentation was given no files and was not run in a module directory'
);
}
}
getPort(argv.port).then(port => {
const server = new Server(port);
let watcher;
server.on('listening', function() {
process.stdout.write(`documentation.js serving on port ${port}\n`);
});
function updateWatcher() {
if (!watcher) {
watcher = chokidar.watch(argv.input);
watcher.on('all', _.debounce(updateServer, 300));
}
documentation
.expandInputs(argv.input, argv)
.then(files => {
watcher.add(
files.map(data => (typeof data === 'string' ? data : data.file))
);
})
.catch(err => {
/* eslint no-console: 0 */
return server.setFiles([errorPage(err)]).start();
});
}
function updateServer() {
documentation
.build(argv.input, argv)
.then(comments => documentation.formats.html(comments, argv))
.then(files => {
if (argv.watch) {
updateWatcher();
}
server.setFiles(files).start();
})
.catch(err => {
return server.setFiles([errorPage(err)]).start();
});
}
updateServer();
});
};