@intervolga/bemjson-loader
Version:
BEM JSON (https://en.bem.info/platform/bemjson/) loader for WebPack 2+
109 lines (94 loc) • 2.96 kB
JavaScript
/**
* Validate BEM JSON
*
* @param {Object} bemJson
* @param {String} fileName
* @return {Array} of validation errors
*/
function validateBemJson(bemJson, fileName) {
let errors = [];
if (Array.isArray(bemJson)) {
bemJson.forEach((childBemJson) => {
errors = errors.concat(validateBemJson(childBemJson, fileName));
});
} else if (bemJson instanceof Object) {
Object.keys(bemJson).forEach((key) => {
const childBemJson = bemJson[key];
errors = errors.concat(validateBemJson(childBemJson, fileName));
});
errors = errors.concat(validateBemJsonNode(bemJson, fileName)); // TODO
}
// TODO
return errors;
}
/**
* Validate single BemJson node https://ru.bem.info/platform/bemjson/
*
* @param {Object} bemJson
* @param {String} fileName
* @return {Array}
*/
function validateBemJsonNode(bemJson, fileName) {
const errors = [];
const fieldTypes = {
block: ['string'],
elem: ['string'],
mods: ['object'],
elemMods: ['object'],
content: ['object', 'string', 'number', 'boolean'],
html: ['string'],
mix: ['object', 'string'],
js: ['boolean', 'object'],
bem: ['boolean'],
attrs: ['object'],
cls: ['string'],
tag: ['boolean', 'string'],
};
Object.keys(bemJson).forEach((bemJsonKey) => {
if (!fieldTypes[bemJsonKey]) {
return;
}
let validType = false;
fieldTypes[bemJsonKey].forEach((fieldType) => {
if (typeof bemJson[bemJsonKey] === fieldType) {
validType = true;
}
});
if (!validType) {
errors.push(new Error('BemJson type mismatch. Value of "' + bemJsonKey +
'" expected to be {' + fieldTypes[bemJsonKey].join('|') +
'}. Got: {' + typeof bemJson[bemJsonKey] + '}. Node: ' +
extractBemJsonNode(bemJson) + '. File: ' + fileName));
}
});
if (bemJson.html && Object.keys(bemJson).length > 1) {
errors.push(new Error('BemJson node has "html" key. ' +
'Other keys will be ignored. Node: ' + extractBemJsonNode(bemJson) +
'. File: ' + fileName));
}
if (bemJson.mods && !(bemJson.elem || bemJson.block)) {
errors.push(new Error('BemJson node has "mods" key, but miss "block" or ' +
'"elem". Key "mods" will be ignored. Node: ' +
extractBemJsonNode(bemJson) + '. File: ' + fileName));
}
if (bemJson.elemMods && !bemJson.elem) {
errors.push(new Error('BemJson node has "elemMods" key, but miss "elem". ' +
'Key "elemMods" will be ignored. Node: ' + extractBemJsonNode(bemJson) +
'. File: ' + fileName));
}
return errors;
}
/**
* Strips all child nodes from BemJson node for print puproses
*
* @param {Object} bemJson
* @return {Object}
*/
function extractBemJsonNode(bemJson) {
const result = JSON.parse(JSON.stringify(bemJson));
Object.keys(result).forEach((key) => {
result[key] = result[key].toString();
});
return JSON.stringify(result, null, 2);
}
module.exports = validateBemJson;