const objectPath = require('object-path'); const utils = require('./utils') const NAME_REGEX = /^[a-z0-9_-]+$/; const DESCRIPTION_REGEX = /^[A-Z]{1}.+\.$/ function required() { return (path, input) => { input = input && input.trim() if(!input) { return `Property '${path}' must be set! value=${input}` } } } function length(opts) { return (path, input) => { input = input && input.trim() || '' if(opts.min && input.length < opts.min) { return `Property '${path}' must have at least ${opts.min} characters! actual=${input.length}` } if(opts.max && input.length > opts.max) { return `Property '${path}' must not have more than ${opts.max} characters! actual=${input.length}` } } } function regex(regex) { return (path, input, msgs) => { input = input && input.trim() if(!input.match(regex)) { return `Property '${path}' must comply to pattern ${regex}! value=${input}` } } } const linterMappings = [ { path: 'name', linters: [ { label: 'is set', validator: required() }, { label: 'has at least 4 characters', validator: length({ min: 4 }) }, { label: 'format is valid', validator: regex(NAME_REGEX) } ] }, { path: 'description', linters: [ { label: 'is set', validator: required() }, { label: 'has at least 4 characters', validator: length({ min: 4 }) }, { label: 'format is valid', validator: regex(DESCRIPTION_REGEX) } ] } ] module.exports.lint = function(spec) { let results = { success: true } linterMappings.forEach(element => { let value = objectPath.get(spec, element.path); element.linters.forEach(linter => { let msg = linter.validator(element.path, value) if(msg) { results.success = false } msg = msg || 'OK' results[element.path] = msg; console.log(utils.formatColumns(utils.formatColumns(element.path, linter.label, 12), msg)) }); }); return results; } module.exports.regex = { NAME_REGEX, DESCRIPTION_REGEX } module.exports.validators = { required, length, regex, }