UNPKG

sdjschema

Version:

SDJSchema(Self Description JSON Schema) is a tool which describes data presence, data type and data constraint to a JSON object

210 lines (164 loc) 7.42 kB
const typeCheck = require("./lib/type-check"); /** * Checks that data is matched by data type * * @public * @param {string} type data type * @param {string|number} name an array index or to be same with property parameter * @param {string|number|boolean|null} the value to the name * @param {string|number} property the name of data member * @return {boolean} Returns false and prints the message if check failed, otherwise returns true */ function validatedType(type, name, val, property) { if ( !typeCheck['is' + type.charAt(0).toUpperCase() + type.slice(1)] ) { console.log(type + " is an invalid data type."); return false; } if ( !typeCheck['is' + type.charAt(0).toUpperCase() + type.slice(1)](val) ) { if ( typeCheck.isPositiveInteger(name) ) { console.log("The value: " + val + " to index: " + name + " of property: " + property + " isn't the type: " + type ); } else { console.log("The value: " + val + " to property: " + property + " isn't the type: " + type ); } return false; } return true; } /** * Checks that data is constrainted by the constraint conditions * * @public * @param {object} cstr constraint object * @param {string|number} name an array index or to be same with property parameter * @param {string|number|boolean|null} the value to the name * @param {string|number} property the name of data member * @return {boolean} Returns false and prints the message if check failed, otherwise returns true */ function validatedConstraint(cstr, name, val, property) { var flag = true; for ( var key in cstr ) { if ( cstr.hasOwnProperty(key) ) { if ( !typeCheck['is' + key.charAt(0).toUpperCase() + key.slice(1)] ) { console.log(key + " is an invalid constraint."); flag = false; } if ( !typeCheck['is' + key.charAt(0).toUpperCase() + key.slice(1)](val, cstr[key]) ) { if ( typeCheck.isPositiveInteger(name) ) { console.log("The constaint: " + key + " is invalid to the index: " + name + " of property: " + property + " with the value: " + val); } else { console.log("The constaint: " + key + " is invalid to the property: " + property + " with the value: " + val); } flag = false; } } } return flag; } /** * Validates JSON members are matched by the descriptions of data presence, type, and constraint. * * @public * @param {object} jdata A JSON object which should be validated * @param {object|null} glb Object for _pfGlobal or null * @return {boolean} Returns false and prints the message if validation failed, otherwise returns true */ function sdjs(jdata, glb = {}) { var vResult = true; for ( var prop in jdata ) { if ( jdata.hasOwnProperty(prop) ) { if ( prop === "_pfGlobal" && typeCheck.isJsonObject(jdata._pfGlobal) ) { glb = jdata._pfGlobal; } if ( typeCheck.isJsonObject(jdata[prop]) ) { vResult = sdjs(jdata[prop], glb); if (!vResult) global.flag = 1; } else if ( Array.isArray(jdata[prop]) ) { for ( var i = 0, len = jdata[prop].length; i < len; i++ ) { if ( typeCheck.isJsonObject(jdata[prop][i]) || Array.isArray(jdata[prop][i]) ) { vResult = sdjs(jdata[prop][i], glb); if (!vResult) global.flag = 1; } else if ( jdata.hasOwnProperty(prop + "_pfidx") ) { var pfk = null; if ( jdata[prop + "_pfidx"].hasOwnProperty("all") && typeof jdata[prop + "_pfidx"].all.type !== 'undefined' ) { pfk = "all"; } else if ( jdata[prop + "_pfidx"].hasOwnProperty("i" + i) && typeof jdata[prop + "_pfidx"]["i" + i].type !== 'undefined' ) { pfk = "i" + i; } if (pfk !== null) { vResult = validatedType(jdata[prop + "_pfidx"][pfk].type, i, jdata[prop][i], prop); if (!vResult) global.flag = 1; if ( typeof jdata[prop + "_pfidx"][pfk].constraint !== 'undefined' ) { vResult = validatedConstraint(jdata[prop + "_pfidx"][pfk].constraint, i, jdata[prop][i], prop); if (!vResult) global.flag = 1; } } } } } else if ( jdata.hasOwnProperty(prop + "_pfsch") && typeof jdata[prop + "_pfsch"] === "string" && jdata[prop + "_pfsch"] !== "" && glb.hasOwnProperty(prop + "_" + jdata[prop + "_pfsch"]) && typeof glb[prop + "_" + jdata[prop + "_pfsch"]].type !== 'undefined' ) { // presence value is 'required' to all members of _pfGlobal value vResult = validatedType(glb[prop + "_" + jdata[prop + "_pfsch"]].type, prop, jdata[prop], prop); if (!vResult) global.flag = 1; if ( typeof glb[prop + "_" + jdata[prop + "_pfsch"]].constraint !== 'undefined' ) { vResult = validatedConstraint(glb[prop + "_" + jdata[prop + "_pfsch"]].constraint, prop, jdata[prop], prop); if (!vResult) global.flag = 1; } } else if ( jdata.hasOwnProperty(prop + "_pfsch") && typeof jdata[prop + "_pfsch"].type !== 'undefined' ) { // presence value is either 'required' or 'implied' vResult = validatedType(jdata[prop + "_pfsch"].type, prop, jdata[prop], prop); if (!vResult) global.flag = 1; if ( typeof jdata[prop + "_pfsch"].constraint !== 'undefined' ) { vResult = validatedConstraint(jdata[prop + "_pfsch"].constraint, prop, jdata[prop], prop); if (!vResult) global.flag = 1; } } else if ( prop.length > 6 && prop.slice(-6) === "_pfsch" && jdata[prop].presence === 'implied' && typeof jdata[prop].type !== 'undefined' && !jdata.hasOwnProperty(prop.slice(0, -6)) ) { var pfn = ""; var pfv = null; if ( jdata.hasOwnProperty(prop.slice(0, -6) + "_default") ) { pfn = prop.slice(0, -6) + "_default"; pfv = jdata[pfn]; } else if ( jdata.hasOwnProperty(prop.slice(0, -6) + "_fixed") ) { pfn = prop.slice(0, -6) + "_fixed"; pfv = jdata[pfn]; } if ( pfv !== null ) { vResult = validatedType(jdata[prop].type, pfn, pfv, prop); if (!vResult) global.flag = 1; if ( typeof jdata[prop].constraint !== 'undefined' ) { vResult = validatedConstraint(jdata[prop].constraint, pfn, pfv, prop); if (!vResult) global.flag = 1; } } } } } if (global.flag !== undefined && global.flag === 1) { global.flag = 0; return false; } return true; } /** * Module exports * @public */ module.exports.valiSdjs = sdjs; module.exports.valiType = validatedType; module.exports.valiConstraint = validatedConstraint;