json-deep-compare
Version:
A powerful library for comparing JSON objects with support for deep comparison, regex validation, and customizable options
1 lines • 2.99 kB
JavaScript
var PathUtils=require("./PathUtils");class Comparator{constructor(e,t,a){this.options=e,this.result=t,this.regexValidator=a}getValueType(e){if(null===e)return"null";if(Array.isArray(e))return"array";if(e instanceof Date)return"date";if(e instanceof RegExp)return"regex";var t=typeof e;if("object"===t){var a=e.constructor.name.toLowerCase();return"object"!==a?a:"object"}return t}compareObjects(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";if(null!==e&&null!==t)if(Array.isArray(e)&&Array.isArray(t))this.compareArrays(e,t,a);else if("object"==typeof e&&"object"==typeof t){var r=Object.keys(e).filter((e=>!this.options.ignoredKeys.includes(e)));for(var s of r){var i=PathUtils.buildPath(a,s);s in t?(this.result.addMatchedKey(i),"object"==typeof e[s]&&null!==e[s]&&"object"==typeof t[s]&&null!==t[s]?this.compareObjects(e[s],t[s],i):this.compareValues(e[s],t[s],i)):this.result.addUnmatchedKey({path:i,value:e[s],message:"Key exists in object 1 but not in object 2"})}if(!this.options.ignoreExtraKeys)for(var l of Object.keys(t))if(!this.options.ignoredKeys.includes(l)&&!(l in e)){var o=PathUtils.buildPath(a,l);this.result.addUnmatchedKey({path:o,value:t[l],message:"Key exists in object 2 but not in object 1"})}}else this.compareValues(e,t,a);else this.compareValues(e,t,a)}compareArrays(e,t,a){e.length!==t.length&&this.result.addUnmatchedValue({path:a,expected:"Array of length ".concat(e.length),actual:"Array of length ".concat(t.length),message:"Array lengths do not match"});for(var r=Math.min(e.length,t.length),s=0;s<r;s++){var i=PathUtils.buildArrayPath(a,s);"object"==typeof e[s]&&null!==e[s]&&"object"==typeof t[s]&&null!==t[s]?this.compareObjects(e[s],t[s],i):this.compareValues(e[s],t[s],i)}for(var l=r;l<e.length;l++){var o=PathUtils.buildArrayPath(a,l);this.result.addUnmatchedValue({path:o,expected:e[l],actual:void 0,message:"Extra element in first array"})}for(var n=r;n<t.length;n++){var c=PathUtils.buildArrayPath(a,n);this.result.addUnmatchedValue({path:c,expected:void 0,actual:t[n],message:"Extra element in second array"})}}compareValues(e,t,a){var r=this.getValueType(e),s=this.getValueType(t);for(var[i,l]of Object.entries(this.options.equivalentValues))if(Array.isArray(l)&&l.includes(e)&&l.includes(t))return void this.result.addMatchedValue({path:a,value:"".concat(e," ≈ ").concat(t),type1:r,type2:s,message:'Values considered equivalent by rule "'.concat(i,'"')});r!==s&&(this.result.addUnmatchedType({path:a,expected:r,actual:s,message:"Types do not match: expected '".concat(r,"', got '").concat(s,"'")}),this.options.strictTypes)||((this.options.strictTypes?e===t:e==t)?this.result.addMatchedValue({path:a,value:e,type:r}):this.result.addUnmatchedValue({path:a,expected:e,actual:t,expectedType:r,actualType:s,message:"Values do not match"}),this.regexValidator.validateValue(t,a))}}module.exports=Comparator;