const objectPath = require('object-path'); const utils = require('./utils') const axios = require('axios') const NAME_REGEX = /^[a-z0-9_-]+$/; const DESCRIPTION_REGEX = /^[A-Z]{1}.+\.$/ const apibuilder_baseurl = "https://api.apibuilder.io" 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}` } } } async function validateOnApiBuilder(spec) { try { let res = await axios.post(`${apibuilder_baseurl}/validations`, spec) return res.data }catch(err) { return err.response.data } } 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.validate = validateOnApiBuilder module.exports.lint = async 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)) }); }); if(results.success) { let apibuilder_result = await validateOnApiBuilder(spec) if(!apibuilder_result) { results.success = false results.apibuilder = apibuilder_result.errors apibuilder_result.errors.forEach(console.error) } } return results; } module.exports.regex = { NAME_REGEX, DESCRIPTION_REGEX } module.exports.validators = { required, length, regex, }