filestojson
Version:
Static data generator based on static files
193 lines (168 loc) • 6.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _frontMatter = require('front-matter');
var _frontMatter2 = _interopRequireDefault(_frontMatter);
var _pngJs = require('png-js');
var _pngJs2 = _interopRequireDefault(_pngJs);
var _joi = require('joi');
var _joi2 = _interopRequireDefault(_joi);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /**
* Static data generator based on static files
*/
/**
* Default options
* @type {Object}
*/
var options = {
content: '',
output: '',
include: ['.md', '.png'],
exclude: ['README.md'],
contentTypes: []
/**
* Reads content directory and return all files
* @param {String} dir Content path
* @param {Array} allFiles Partial list of files and directories
* @return {Array} List of files and directories
*/
};function readDirSync(dir) {
var allFiles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var files = _fs2.default.readdirSync(dir).map(function (f) {
return (0, _path.join)(dir, f);
});
allFiles.push.apply(allFiles, _toConsumableArray(files));
files.forEach(function (f) {
_fs2.default.statSync(f).isDirectory() && readDirSync(f, allFiles);
});
return allFiles;
}
/**
* Get data from list of files filtered based on options
* @param {Array} allFiles List of files and directories
* @return {Array} Updated list of files with content
*/
function getData() {
var allFiles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var config = arguments[1];
var files = allFiles.reduce(function (memo, iteratee) {
var filePath = _path2.default.parse(iteratee);
if (config.include.includes(filePath.ext) && !config.exclude.includes(filePath.base)) {
var newFile = {
file: iteratee.replace(config.content, ''),
dir: filePath.dir.replace(config.content, ''),
name: filePath.name,
base: filePath.base,
ext: filePath.ext
};
if (filePath.ext === '.md') {
var file = _fs2.default.readFileSync(iteratee, { encoding: 'utf8' });
var frontMatter = (0, _frontMatter2.default)(file);
newFile.attr = frontMatter.attributes;
newFile.body = frontMatter.body;
} else if (filePath.ext === '.png') {
var image = new _pngJs2.default.load(iteratee);
newFile.width = image.width;
newFile.height = image.height;
}
memo.push(newFile);
}
return memo;
}, []);
return files;
}
/**
* Translate data based on content types
* @param {Array} file List of contents
* @return {Array} Updated list of contents
*/
function translate(content, contentTypes) {
var output = {};
content.forEach(function (each) {
var base = _path2.default.parse(each.file).base;
if (base === 'index.md') {
var type = each.dir.split('/').pop();
var contentTypeTranslation = contentTypes.find(function (contentType) {
return contentType[type];
});
if (contentTypeTranslation && contentTypeTranslation[type]) {
output[type] = contentTypeTranslation[type](content, type);
}
}
});
return output;
}
/**
* Write output data in file system
* @param {String} filename Output file name
* @param {Array} content List of contents
* @return {String} Stringified list of contents
*/
function write(filename, content) {
var json = JSON.stringify(content, function (key, value) {
return value === undefined ? null : value;
});
_fs2.default.writeFileSync(filename, json);
return json;
}
/**
* Validate configuration
* @param {Object} config Configuration object
* @return {null} It will just throw error if invalid
*/
function validateConfig(config) {
var customJoi = _joi2.default.extend(function (joi) {
return {
base: joi.string(),
name: 'file',
language: {
exists: 'file or directory must exists'
},
rules: [{
name: 'exists',
validate: function validate(params, value, state, options) {
if (!_fs2.default.existsSync(value)) {
return this.createError('file.exists', { v: value }, state, options);
}
return value;
}
}]
};
});
var schema = _joi2.default.object().keys({
content: customJoi.file().exists().required(),
output: _joi2.default.string().required(),
include: _joi2.default.array().min(1).items(_joi2.default.string()).required(),
exclude: _joi2.default.array().min(1).items(_joi2.default.string()).required(),
contentTypes: _joi2.default.array().min(1).items(_joi2.default.object()).required()
});
var result = _joi2.default.validate(config, schema, function (err, value) {
if (err !== null) {
throw err;
}
});
}
/**
* Run script
*/
function filestojson() {
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : options;
try {
validateConfig(config);
var content = readDirSync(config.content);
content = getData(content, config);
content = translate(content, config.contentTypes);
content = write(config.output, content);
console.log('File written on ' + config.output);
return content;
} catch (e) {
console.log('Error: ', e);
}
}
exports.default = filestojson;