sassdoc
Version:
Release the docs!
579 lines (444 loc) • 15.7 kB
JavaScript
;
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');
}