UNPKG

sassdoc

Version:
579 lines (444 loc) 15.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.errors = exports.sorter = exports.Parser = exports.Logger = exports.Environment = undefined; var _getOwnPropertyNames = require('babel-runtime/core-js/object/get-own-property-names'); var _getOwnPropertyNames2 = _interopRequireDefault(_getOwnPropertyNames); var _find = require('babel-runtime/core-js/array/find'); var _find2 = _interopRequireDefault(_find); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); /** * Source directory fetching and parsing. */ var baseDocumentize = function () { var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(env) { var filter, streams, pipeline; return _regenerator2.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: filter = parseFilter(env); filter.promise.then(function (data) { env.logger.log('Folder `' + env.src + '` successfully parsed.'); env.data = data; onEmpty(data, env); env.logger.debug(function () { _fs2.default.writeFile('sassdoc-data.json', (0, _stringify2.default)(data, null, 2) + '\n', function (err) { if (err) throw err; }); return 'Dumping data to `sassdoc-data.json`.'; }); }); streams = [_vinylFs2.default.src(env.src), (0, _recurse2.default)(), (0, _exclude2.default)(env.exclude || []), (0, _sassConvert2.default)({ from: 'sass', to: 'scss' }), filter]; pipeline = function pipeline() { return new _promise2.default(function (resolve, reject) { _multipipe2.default.apply(undefined, streams.concat([function (err) { return err ? reject(err) : resolve(); }])).resume(); // Drain. }); }; _context4.prev = 4; _context4.next = 7; return pipeline(); case 7: _context4.next = 9; return filter.promise; case 9: _context4.next = 15; break; case 11: _context4.prev = 11; _context4.t0 = _context4['catch'](4); env.emit('error', _context4.t0); throw _context4.t0; case 15: return _context4.abrupt('return', env.data); case 16: case 'end': return _context4.stop(); } } }, _callee4, this, [[4, 11]]); })); return function baseDocumentize(_x5) { return _ref4.apply(this, arguments); }; }(); /** * Return a function taking optional `src` string or array, and optional * `env` object (arguments are found by their type). * * If `src` is set, proxy to `documentize`, otherwise `stream`. * * Both functions will be passed the `env` object, which will have a * `src` key. */ exports.parseFilter = parseFilter; exports.ensureEnvironment = ensureEnvironment; exports.default = sassdoc; exports.parse = parse; var _utils = require('./utils'); var _environment = require('./environment'); var _environment2 = _interopRequireDefault(_environment); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var _parser = require('./parser'); var _parser2 = _interopRequireDefault(_parser); var _errors = require('./errors'); var errors = _interopRequireWildcard(_errors); var _sorter = require('./sorter'); var _sorter2 = _interopRequireDefault(_sorter); var _exclude = require('./exclude'); var _exclude2 = _interopRequireDefault(_exclude); var _recurse = require('./recurse'); var _recurse2 = _interopRequireDefault(_recurse); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _lodash = require('lodash.difference'); var _lodash2 = _interopRequireDefault(_lodash); var _safeWipe = require('safe-wipe'); var _safeWipe2 = _interopRequireDefault(_safeWipe); var _vinylFs = require('vinyl-fs'); var _vinylFs2 = _interopRequireDefault(_vinylFs); var _sassConvert = require('sass-convert'); var _sassConvert2 = _interopRequireDefault(_sassConvert); var _multipipe = require('multipipe'); var _multipipe2 = _interopRequireDefault(_multipipe); var _through = require('through2'); var _through2 = _interopRequireDefault(_through); var _mkdirp = require('mkdirp'); var _mkdirp2 = _interopRequireDefault(_mkdirp); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Expose lower API blocks. */ exports.Environment = _environment2.default; exports.Logger = _logger2.default; exports.Parser = _parser2.default; exports.sorter = _sorter2.default; exports.errors = errors; /** * Boostrap Parser and AnnotationsApi, execute parsing phase. * @return {Stream} * @return {Promise} - as a property of Stream. */ function parseFilter() { var env = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; env = ensureEnvironment(env); var parser = new _parser2.default(env, env.theme && env.theme.annotations); return parser.stream(); } /** * Ensure a proper Environment Object and events. * @param {Object} config - can be falsy. * @return {Object} */ function ensureEnvironment(config) { var onError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (e) { throw e; }; if (config instanceof _environment2.default) { config.on('error', onError); return config; } var logger = ensureLogger(config); var env = new _environment2.default(logger, config && config.verbose, config && config.strict); env.on('error', onError); env.load(config); env.postProcess(); return env; } /** * @param {Object} config * @return {Logger} */ function ensureLogger(config) { if (!_utils.is.object(config) || !('logger' in config)) { // Get default logger. return new _logger2.default(config && config.verbose, process.env.SASSDOC_DEBUG); } var logger = (0, _logger.checkLogger)(config.logger); delete config.logger; return logger; } /** * Default public API method. * @param {String | Array} src * @param {Object} env * @return {Promise | Stream} * @see srcEnv */ function sassdoc() { /** * Execute full SassDoc sequence from a source directory. * @return {Promise} */ var documentize = function () { var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(env) { var data; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: init(env); _context.next = 3; return baseDocumentize(env); case 3: data = _context.sent; _context.prev = 4; _context.next = 7; return refresh(env); case 7: _context.next = 9; return theme(env); case 9: okay(env); _context.next = 16; break; case 12: _context.prev = 12; _context.t0 = _context['catch'](4); env.emit('error', _context.t0); throw _context.t0; case 16: return _context.abrupt('return', data); case 17: case 'end': return _context.stop(); } } }, _callee, this, [[4, 12]]); })); return function documentize(_x3) { return _ref.apply(this, arguments); }; }(); /** * Execute full SassDoc sequence from a Vinyl files stream. * @return {Stream} * @return {Promise} - as a property of Stream. */ return srcEnv(documentize, stream).apply(undefined, arguments); /** * Safely wipe and re-create the destination directory. * @return {Promise} */ function refresh(env) { return (0, _safeWipe2.default)(env.dest, { force: true, parent: _utils.is.string(env.src) || _utils.is.array(env.src) ? (0, _utils.g2b)(env.src) : null, silent: true }).then(function () { return (0, _mkdirp2.default)(env.dest); }).then(function () { env.logger.log('Folder `' + env.displayDest + '` successfully refreshed.'); }).catch(function (err) { // Friendly error for already existing directory. throw new errors.SassDocError(err.message); }); } /** * Render theme with parsed data context. * @return {Promise} */ function theme(env) { var promise = env.theme(env.dest, env); if (!_utils.is.promise(promise)) { var type = Object.prototype.toString.call(promise); throw new errors.Error('Theme didn\'t return a promise, got ' + type + '.'); } return promise.then(function () { var displayTheme = env.displayTheme || 'anonymous'; env.logger.log('Theme `' + displayTheme + '` successfully rendered.'); }); }function stream(env) { var filter = parseFilter(env); filter.promise.then(function (data) { env.logger.log('Sass sources successfully parsed.'); env.data = data; onEmpty(data, env); }); /** * Returned Promise await the full sequence, * instead of just the parsing step. */ filter.promise = new _promise2.default(function (resolve, reject) { var documentize = function () { var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; init(env); _context2.next = 4; return refresh(env); case 4: _context2.next = 6; return theme(env); case 6: okay(env); resolve(); _context2.next = 15; break; case 10: _context2.prev = 10; _context2.t0 = _context2['catch'](0); reject(_context2.t0); env.emit('error', _context2.t0); throw _context2.t0; case 15: case 'end': return _context2.stop(); } } }, _callee2, this, [[0, 10]]); })); return function documentize() { return _ref2.apply(this, arguments); }; }(); filter.on('end', documentize).on('error', function (err) { return env.emit('error', err); }).resume(); // Drain. }); return filter; } } /** * Parse and return data object. * @param {String | Array} src * @param {Object} env * @return {Promise | Stream} * @see srcEnv */ function parse() { /** * @return {Promise} */ var documentize = function () { var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(env) { var data; return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return baseDocumentize(env); case 2: data = _context3.sent; return _context3.abrupt('return', data); case 4: case 'end': return _context3.stop(); } } }, _callee3, this); })); return function documentize(_x4) { return _ref3.apply(this, arguments); }; }(); /** * Don't pass files through, but pass final data at the end. * @return {Stream} */ return srcEnv(documentize, stream).apply(undefined, arguments);function stream(env) { var parseStream = parseFilter(env); var filter = _through2.default.obj(function (file, enc, cb) { return cb(); }, function (cb) { var _this = this; parseStream.promise.then(function (data) { _this.push(data); cb(); }, cb); }); return (0, _multipipe2.default)(parseStream, filter); } }function srcEnv(documentize, stream) { return function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var src = (0, _find2.default)(args, function (a) { return _utils.is.string(a) || _utils.is.array(a); }); var env = (0, _find2.default)(args, _utils.is.plainObject); env = ensureEnvironment(env); env.logger.debug('process.argv:', function () { return (0, _stringify2.default)(process.argv); }); env.logger.debug('sassdoc version:', function () { return require('../package.json').version; }); env.logger.debug('node version:', function () { return process.version.substr(1); }); env.logger.debug('npm version:', function () { var prefix = _path2.default.resolve(process.execPath, '../../lib'); var pkg = _path2.default.resolve(prefix, 'node_modules/npm/package.json'); try { return require(pkg).version; } catch (e) { return 'unknown'; } }); env.logger.debug('platform:', function () { return process.platform; }); env.logger.debug('cwd:', function () { return process.cwd(); }); env.src = src; env.logger.debug('env:', function () { var clone = {}; (0, _lodash2.default)((0, _getOwnPropertyNames2.default)(env), ['domain', '_events', '_maxListeners', 'logger']).forEach(function (k) { return clone[k] = env[k]; }); return (0, _stringify2.default)(clone, null, 2); }); var task = env.src ? documentize : stream; env.logger.debug('task:', function () { return env.src ? 'documentize' : 'stream'; }); return task(env); }; } /** * Warn user on empty documentation. * @param {Array} data * @param {Object} env */ function onEmpty(data, env) { var message = 'SassDoc could not find anything to document.\n\n * Are you still using `/**` comments ? They\'re no more supported since 2.0.\n See <http://sassdoc.com/upgrading/#c-style-comments>.\n'; if (!data.length && env.verbose) { env.emit('warning', new errors.Warning(message)); } } /** * Init timer. * @param {Object} env */ function init(env) { env.logger.time('SassDoc'); } /** * Log final success message. * @param {Object} env */ function okay(env) { env.logger.log('Process over. Everything okay!'); env.logger.timeEnd('SassDoc', '%s completed after %dms'); }