Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mjml-validator

Package Overview
Dependencies
Maintainers
6
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mjml-validator - npm Package Compare versions

Comparing version 4.7.1 to 4.8.0

36

lib/dependencies.js
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.registerDependencies = void 0;
exports.default = exports.registerDependencies = exports.assignDependencies = void 0;
var _isArray2 = _interopRequireDefault(require("lodash/isArray"));
const assignDependencies = (target, ...sources) => {
for (const source of sources) {
for (const tag of Object.keys(source)) {
const list = [];
var _mergeWith2 = _interopRequireDefault(require("lodash/mergeWith"));
if (target[tag]) {
list.push(...target[tag]);
}
// eslint-disable-next-line consistent-return
function mergeArrays(objValue, srcValue) {
if ((0, _isArray2["default"])(objValue) && (0, _isArray2["default"])(srcValue)) {
return objValue.concat(srcValue);
if (source[tag]) {
list.push(...source[tag]);
}
target[tag] = Array.from(new Set(list));
}
}
}
var dependencies = {};
return target;
};
var registerDependencies = function registerDependencies(dep) {
return (0, _mergeWith2["default"])(dependencies, dep, mergeArrays);
exports.assignDependencies = assignDependencies;
const dependencies = {};
const registerDependencies = dep => {
assignDependencies(dependencies, dep);
};

@@ -29,2 +37,2 @@

var _default = dependencies;
exports["default"] = _default;
exports.default = _default;

@@ -10,7 +10,7 @@ "use strict";

});
exports["default"] = MJMLValidator;
exports.default = MJMLValidator;
Object.defineProperty(exports, "rulesCollection", {
enumerable: true,
get: function get() {
return _MJMLRulesCollection["default"];
get: function () {
return _MJMLRulesCollection.default;
}

@@ -20,3 +20,3 @@ });

enumerable: true,
get: function get() {
get: function () {
return _MJMLRulesCollection.registerRule;

@@ -27,4 +27,4 @@ }

enumerable: true,
get: function get() {
return _dependencies["default"];
get: function () {
return _dependencies.default;
}

@@ -34,22 +34,14 @@ });

enumerable: true,
get: function get() {
get: function () {
return _dependencies.registerDependencies;
}
});
Object.defineProperty(exports, "assignDependencies", {
enumerable: true,
get: function () {
return _dependencies.assignDependencies;
}
});
exports.formatValidationError = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _values2 = _interopRequireDefault(require("lodash/values"));
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _filter2 = _interopRequireDefault(require("lodash/filter"));
var _concat2 = _interopRequireDefault(require("lodash/concat"));
var _flatten2 = _interopRequireDefault(require("lodash/flatten"));
var _ruleError = _interopRequireDefault(require("./rules/ruleError"));

@@ -61,28 +53,41 @@

var SKIP_ELEMENTS = ['mjml'];
var formatValidationError = _ruleError["default"];
const SKIP_ELEMENTS = ['mjml'];
const formatValidationError = _ruleError.default;
exports.formatValidationError = formatValidationError;
function MJMLValidator(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var children = element.children,
tagName = element.tagName;
var errors;
var skipElements = options.skipElements || SKIP_ELEMENTS;
function MJMLValidator(element, options = {}) {
const {
children,
tagName
} = element;
const errors = [];
const skipElements = options.skipElements || SKIP_ELEMENTS;
if (!(0, _includes2["default"])(skipElements, tagName)) {
errors = (0, _flatten2["default"])(_concat2["default"].apply(void 0, [errors].concat((0, _toConsumableArray2["default"])((0, _values2["default"])(_MJMLRulesCollection["default"]).map(function (rule) {
return rule(element, (0, _objectSpread2["default"])({
skipElements: skipElements
}, options));
})))));
if (options.dependencies == null) {
console.warn('"dependencies" option should be provided to mjml validator');
}
if (!skipElements.includes(tagName)) {
for (const rule of Object.values(_MJMLRulesCollection.default)) {
const ruleError = rule(element, {
dependencies: _dependencies.default,
skipElements,
...options
});
if (Array.isArray(ruleError)) {
errors.push(...ruleError);
} else if (ruleError) {
errors.push(ruleError);
}
}
}
if (children && children.length > 0) {
errors = (0, _flatten2["default"])(_concat2["default"].apply(void 0, [errors].concat((0, _toConsumableArray2["default"])(children.map(function (child) {
return MJMLValidator(child, options);
})))));
for (const child of children) {
errors.push(...MJMLValidator(child, options));
}
}
return (0, _filter2["default"])(errors);
return errors;
}
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

@@ -11,15 +9,25 @@

exports.registerRule = registerRule;
exports["default"] = void 0;
exports.default = void 0;
var _mapKeys2 = _interopRequireDefault(require("lodash/mapKeys"));
var _validAttributes = _interopRequireDefault(require("./rules/validAttributes"));
var _warning = _interopRequireDefault(require("warning"));
var _validChildren = _interopRequireDefault(require("./rules/validChildren"));
var rules = _interopRequireWildcard(require("./rules"));
var _validTag = _interopRequireDefault(require("./rules/validTag"));
var MJMLRulesCollection = {};
var _validTypes = _interopRequireDefault(require("./rules/validTypes"));
var _errorAttr = _interopRequireDefault(require("./rules/errorAttr"));
const MJMLRulesCollection = {
validAttributes: _validAttributes.default,
validChildren: _validChildren.default,
validTag: _validTag.default,
validTypes: _validTypes.default,
errorAttr: _errorAttr.default
};
function registerRule(rule, name) {
if (typeof rule !== 'function') {
return (0, _warning["default"])(false, 'Your rule must be a function');
return console.error('Your rule must be a function');
}

@@ -36,6 +44,3 @@

(0, _mapKeys2["default"])(rules, function (func, name) {
return registerRule(func, name);
});
var _default = MJMLRulesCollection;
exports["default"] = _default;
exports.default = _default;

@@ -8,3 +8,3 @@ "use strict";

});
exports["default"] = errorAttr;
exports.default = errorAttr;

@@ -14,12 +14,15 @@ var _ruleError = _interopRequireDefault(require("./ruleError"));

function errorAttr(element) {
var errors = element.errors;
const {
errors
} = element;
if (!errors) return null;
return errors.map(function (error) {
return errors.map(error => {
switch (error.type) {
case 'include':
{
var _error$params = error.params,
file = _error$params.file,
partialPath = _error$params.partialPath;
return (0, _ruleError["default"])("mj-include fails to read file : ".concat(file, " at ").concat(partialPath), element);
const {
file,
partialPath
} = error.params;
return (0, _ruleError.default)(`mj-include fails to read file : ${file} at ${partialPath}`, element);
}

@@ -26,0 +29,0 @@

@@ -10,4 +10,4 @@ "use strict";

enumerable: true,
get: function get() {
return _validAttributes["default"];
get: function () {
return _validAttributes.default;
}

@@ -17,4 +17,4 @@ });

enumerable: true,
get: function get() {
return _validChildren["default"];
get: function () {
return _validChildren.default;
}

@@ -24,4 +24,4 @@ });

enumerable: true,
get: function get() {
return _validTag["default"];
get: function () {
return _validTag.default;
}

@@ -31,4 +31,4 @@ });

enumerable: true,
get: function get() {
return _validTypes["default"];
get: function () {
return _validTypes.default;
}

@@ -38,4 +38,4 @@ });

enumerable: true,
get: function get() {
return _errorAttr["default"];
get: function () {
return _errorAttr.default;
}

@@ -42,0 +42,0 @@ });

@@ -6,24 +6,27 @@ "use strict";

});
exports["default"] = ruleError;
exports.default = ruleError;
function formatInclude(element) {
var includedIn = element.includedIn;
const {
includedIn
} = element;
if (!(includedIn && includedIn.length)) return '';
var formattedIncluded = includedIn.slice().reverse().map(function (_ref) {
var line = _ref.line,
file = _ref.file;
return "line ".concat(line, " of file ").concat(file);
}).join(', itself included at ');
return ", included at ".concat(formattedIncluded);
const formattedIncluded = includedIn.slice().reverse().map(({
line,
file
}) => `line ${line} of file ${file}`).join(', itself included at ');
return `, included at ${formattedIncluded}`;
}
function ruleError(message, element) {
var line = element.line,
tagName = element.tagName,
absoluteFilePath = element.absoluteFilePath;
const {
line,
tagName,
absoluteFilePath
} = element;
return {
line: line,
message: message,
tagName: tagName,
formattedMessage: "Line ".concat(line, " of ").concat(absoluteFilePath).concat(formatInclude(element), " (").concat(tagName, ") \u2014 ").concat(message)
line,
message,
tagName,
formattedMessage: `Line ${line} of ${absoluteFilePath}${formatInclude(element)} (${tagName}) — ${message}`
};

@@ -30,0 +33,0 @@ }

@@ -8,21 +8,16 @@ "use strict";

});
exports["default"] = validateAttribute;
exports.default = validateAttribute;
var _filter2 = _interopRequireDefault(require("lodash/filter"));
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _keys2 = _interopRequireDefault(require("lodash/keys"));
var _concat2 = _interopRequireDefault(require("lodash/concat"));
var _ruleError = _interopRequireDefault(require("./ruleError"));
var WHITELIST = ['mj-class', 'css-class'];
const WHITELIST = ['mj-class', 'css-class'];
function validateAttribute(element, _ref) {
var components = _ref.components;
var attributes = element.attributes,
tagName = element.tagName;
var Component = components[tagName];
function validateAttribute(element, {
components
}) {
const {
attributes,
tagName
} = element;
const Component = components[tagName];

@@ -33,6 +28,4 @@ if (!Component) {

var availableAttributes = (0, _concat2["default"])((0, _keys2["default"])(Component.allowedAttributes), WHITELIST);
var unknownAttributes = (0, _filter2["default"])((0, _keys2["default"])(attributes), function (attribute) {
return !(0, _includes2["default"])(availableAttributes, attribute);
});
const availableAttributes = [...Object.keys(Component.allowedAttributes || {}), ...WHITELIST];
const unknownAttributes = Object.keys(attributes).filter(attribute => !availableAttributes.includes(attribute));

@@ -43,11 +36,12 @@ if (unknownAttributes.length === 0) {

var _attribute$illegal = {
const {
attribute,
illegal
} = {
attribute: unknownAttributes.length > 1 ? 'Attributes' : 'Attribute',
illegal: unknownAttributes.length > 1 ? 'are illegal' : 'is illegal'
},
attribute = _attribute$illegal.attribute,
illegal = _attribute$illegal.illegal;
return (0, _ruleError["default"])("".concat(attribute, " ").concat(unknownAttributes.join(', '), " ").concat(illegal), element);
};
return (0, _ruleError.default)(`${attribute} ${unknownAttributes.join(', ')} ${illegal}`, element);
}
module.exports = exports.default;

@@ -8,20 +8,16 @@ "use strict";

});
exports["default"] = validChildren;
exports.default = validChildren;
var _keys2 = _interopRequireDefault(require("lodash/keys"));
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _filter2 = _interopRequireDefault(require("lodash/filter"));
var _dependencies = _interopRequireDefault(require("../dependencies"));
var _ruleError = _interopRequireDefault(require("./ruleError"));
function validChildren(element, _ref) {
var components = _ref.components,
skipElements = _ref.skipElements;
var children = element.children,
tagName = element.tagName;
var Component = components[tagName];
function validChildren(element, {
components,
dependencies,
skipElements
}) {
const {
children,
tagName
} = element;
const Component = components[tagName];

@@ -32,22 +28,19 @@ if (!Component || !children || !children.length) {

return (0, _filter2["default"])(children.map(function (child) {
var childTagName = child.tagName;
var ChildComponent = components[childTagName];
var parentDependencies = _dependencies["default"][tagName] || [];
const errors = [];
if (!ChildComponent || (0, _includes2["default"])(skipElements, childTagName) || (0, _includes2["default"])(parentDependencies, childTagName) || parentDependencies.some(function (dep) {
return dep instanceof RegExp && dep.test(childTagName);
})) {
return null;
for (const child of children) {
const childTagName = child.tagName;
const ChildComponent = components[childTagName];
const parentDependencies = dependencies[tagName] || [];
const childIsValid = !ChildComponent || skipElements.includes(childTagName) || parentDependencies.includes(childTagName) || parentDependencies.some(dep => dep instanceof RegExp && dep.test(childTagName));
if (childIsValid === false) {
const allowedDependencies = Object.keys(dependencies).filter(key => dependencies[key].includes(childTagName) || dependencies[key].some(dep => dep instanceof RegExp && dep.test(childTagName)));
errors.push((0, _ruleError.default)(`${childTagName} cannot be used inside ${tagName}, only inside: ${allowedDependencies.join(', ')}`, child));
}
}
var allowedDependencies = (0, _keys2["default"])(_dependencies["default"]).filter(function (key) {
return (0, _includes2["default"])(_dependencies["default"][key], childTagName) || _dependencies["default"][key].some(function (dep) {
return dep instanceof RegExp && dep.test(childTagName);
});
});
return (0, _ruleError["default"])("".concat(childTagName, " cannot be used inside ").concat(tagName, ", only inside: ").concat(allowedDependencies.join(', ')), child);
}));
return errors;
}
module.exports = exports.default;

@@ -8,19 +8,20 @@ "use strict";

});
exports["default"] = validateTag;
exports.default = validateTag;
var _includes2 = _interopRequireDefault(require("lodash/includes"));
var _ruleError = _interopRequireDefault(require("./ruleError"));
// Tags that have no associated components but are allowed even so
var componentLessTags = ['mj-all', 'mj-class', 'mj-selector', 'mj-html-attribute'];
const componentLessTags = ['mj-all', 'mj-class', 'mj-selector', 'mj-html-attribute'];
function validateTag(element, _ref) {
var components = _ref.components;
var tagName = element.tagName;
if ((0, _includes2["default"])(componentLessTags, tagName)) return null;
var Component = components[tagName];
function validateTag(element, {
components
}) {
const {
tagName
} = element;
if (componentLessTags.includes(tagName)) return null;
const Component = components[tagName];
if (!Component) {
return (0, _ruleError["default"])("Element ".concat(tagName, " doesn't exist or is not registered"), element);
return (0, _ruleError.default)(`Element ${tagName} doesn't exist or is not registered`, element);
}

@@ -27,0 +28,0 @@

@@ -8,16 +8,15 @@ "use strict";

});
exports["default"] = validateType;
exports.default = validateType;
var _map2 = _interopRequireDefault(require("lodash/map"));
var _compact2 = _interopRequireDefault(require("lodash/compact"));
var _ruleError = _interopRequireDefault(require("./ruleError"));
function validateType(element, _ref) {
var components = _ref.components,
initializeType = _ref.initializeType;
var attributes = element.attributes,
tagName = element.tagName;
var Component = components[tagName];
function validateType(element, {
components,
initializeType
}) {
const {
attributes,
tagName
} = element;
const Component = components[tagName];

@@ -28,13 +27,20 @@ if (!Component) {

return (0, _compact2["default"])((0, _map2["default"])(attributes, function (value, attr) {
var attrType = Component.allowedAttributes && Component.allowedAttributes[attr];
if (!attrType) return null; // attribute not allowed
const errors = [];
var TypeChecker = initializeType(attrType);
var result = new TypeChecker(value);
if (result.isValid()) return null;
return (0, _ruleError["default"])("Attribute ".concat(attr, " ").concat(result.getErrorMessage()), element);
}));
for (const [attr, value] of Object.entries(attributes)) {
const attrType = Component.allowedAttributes && Component.allowedAttributes[attr];
if (attrType) {
const TypeChecker = initializeType(attrType);
const result = new TypeChecker(value);
if (result.isValid() === false) {
errors.push((0, _ruleError.default)(`Attribute ${attr} ${result.getErrorMessage()}`, element));
}
}
}
return errors;
}
module.exports = exports.default;
{
"name": "mjml-validator",
"description": "mjml-validator",
"version": "4.7.1",
"version": "4.8.0",
"main": "lib/index.js",

@@ -24,5 +24,3 @@ "files": [

"dependencies": {
"@babel/runtime": "^7.8.7",
"lodash": "^4.17.15",
"warning": "^3.0.0"
"@babel/runtime": "^7.8.7"
},

@@ -33,3 +31,3 @@ "devDependencies": {

},
"gitHead": "6bb3e08efb912765d5195d35dc19ce61cdd6306a"
"gitHead": "6037a02810ea9a0cb62965ba81712fdf536b958b"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc