UNPKG

smalley

Version:

Validates data passed in against a validation definition config.

139 lines (120 loc) 4.46 kB
'use strict'; var appRoot = require('app-root-path'), getValDefs = require('./lib/getValDefs'), async = require('async'), unwind = require('unwinder'), validators = require('./lib/validators'); module.exports.validate = function(input, callback){ async.waterfall( [ // Get the definitions ---------------------------------------- function(wfCallback) { // The preValidation here function simultaneously grabs the definitions from the given folder // and flattens the given object. preValidation(input, function(err, results) { if(err) wfCallback(err); else wfCallback(null, results); }); }, // Run the validation testing -------------------------------- // Iterates through the object checking for required attributes and types function(data, wfCallback){ validationRunner(data[1], data[0], function(err, results) { if(err){ wfCallback(err); } else{ wfCallback(null, results); } }); } ], // Send back the results ------------------------------------- // The success response is just a string indicating that things passed validation. function(err, results) { if(err){ callback(err); } else{ if (results.length === 0) callback(null, "Data was validated."); else callback(null, "Could not validate " + results.join(", ") + ", but everything else was valid."); } } ); }; // Validation =========================================================================================== // Input- data <object>, definitions <object>, callback <function> // Output- err <Error>, message <string> //======================================================================================================= var validationRunner = function(data, definitions, callback) { var noDef = []; //for tracking attributes without definitions if(definitions === undefined || definitions === null) return callback(new Error("No definitions were found at the given file path.")); // look for missing, but required attributes------------------------------------- for(var def in definitions) { if(definitions[def].require === true && data[def] === undefined) return callback(new Error(def + " did not exist, but is a required attribute.")); } // start checking attributes against defs----------------------------------------------------------- var count = 0; for(var attr in data) { //if the definition is undefined, add the attr to the list of non-defined attrs if(definitions[attr] === undefined){ count++; noDef.push(attr); } //if the attributes have all been checked, return back to smalley if(count === Object.keys(data).length) return callback(null, noDef); // if the definitions have the attr, check it if(definitions[attr] !== undefined){ async.parallel( [ //Match types to defs function(pCallback) { validators.typeCheck(data, attr, definitions, noDef, pCallback); }, //if a regexp is defined, check for matching function(pCallback) { validators.matchCheck(data, attr, definitions, pCallback); }, function(pCallback) { validators.lengthCheck(data, attr, definitions, pCallback); } ], function(err, finished){ if(err) return callback(err); else{ count++; if(count === Object.keys(data).length) return callback(null, noDef); } }); } } }; module.exports.validationRunner = validationRunner; // preValidation ======================================================================================= // Input- input<object> (has definitionPath and data attributes) // Output- results <array> (results[0] = definitions, results[1] = flattnened object) //======================================================================================================= var preValidation = function(input, callback) { async.parallel( [ //get the definitions read in function(pCallback) { getValDefs(input.definitionPath, pCallback); }, //flatten the object passed in for reading function(pCallback){ unwind.flatten(input.data, pCallback); } ], callback); }; module.exports.preValidation = preValidation;