api-cli/src/linter.js

86 lines
2.3 KiB
JavaScript

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,
}