zexson_toolkit
Version:
Zexson Toolkit is a powerful encryption and tokenization library developed by Zexson Team. It offers proprietary encryption algorithms, high-security random token generation, and advanced object comparison features. It includes many advanced security func
111 lines (110 loc) • 4.55 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isEquals = void 0;
/**
* Deeply compares two objects or arrays for equality, with optional type checking.
*
* @template T - Generic type extending Record<string, any>
* @param {T} obj1 - First object to compare
* @param {T} obj2 - Second object to compare
* @param {CompareOptions} [options={ checkType: false }] - Comparison options
* @param {boolean} options.checkType - When true, compares types instead of values
* @returns {boolean} Returns true if objects are equal based on comparison criteria
*
* @example
* // Compare values
* const obj1 = { name: "John", age: 30, details: { city: "New York" } }
* const obj2 = { name: "John", age: 30, details: { city: "New York" } }
* isEqualsObject(obj1, obj2) // true
*
* // Compare types
* const obj3 = { name: "John", age: 25 }
* const obj4 = { name: "Jane", age: 30 }
* isEqualsObject(obj3, obj4, { checkType: true }) // true
*
* @since 1.1.2
* @category Comparison
* @public
*/
const isEquals = (obj1, obj2, options = { checkType: false }) => {
if (!obj2 && options.schema && obj1)
return validateSchema(obj1, options.schema);
if (options.schema) {
options.checkType = true;
const schemaValid = validateSchema(obj1, options.schema) && validateSchema(obj2, options.schema);
if (!schemaValid)
return false;
}
if (typeof obj1 !== 'object' || typeof obj2 !== 'object')
return options.checkType ? typeof obj1 === typeof obj2 : obj1 === obj2;
if (obj1 === null || obj2 === null)
return options.checkType ? typeof obj1 === typeof obj2 : obj1 === obj2;
if (Array.isArray(obj1) && Array.isArray(obj2)) {
if (obj1.length !== obj2.length)
return false;
return obj1.every((item, index) => (0, exports.isEquals)(item, obj2[index], options));
}
if ((typeof obj1 == 'object' && typeof obj2 == 'object')) {
if ((!Array.isArray(obj1) && Array.isArray(obj2)))
return false;
if (Array.isArray(obj1) && !Array.isArray(obj2))
return false;
}
const keys1 = Object.keys(obj1), keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length)
return false;
return keys1.every(key => {
if (!obj2.hasOwnProperty(key))
return false;
return (0, exports.isEquals)(obj1[key], obj2[key], options);
});
};
exports.isEquals = isEquals;
function validateSchema(obj, schema) {
const schemaKeys = Object.keys(schema), objKeys = Object.keys(obj);
if (schemaKeys.length !== objKeys.length)
return false;
if (!schemaKeys.every(key => objKeys.includes(key)))
return false;
for (const [key, schemaType] of Object.entries(schema)) {
const value = obj[key];
if (typeof schemaType === 'string') {
if (typeof value !== schemaType)
return false;
}
else if (typeof schemaType === 'object' && 'type' in schemaType) {
if (schemaType.type === 'array') {
if (!Array.isArray(value))
return false;
if (schemaType.items) {
if (!value.every(item => {
if (schemaType.items?.type === 'string' && schemaType.items.enum)
return schemaType.items.enum.includes(item);
return validateValue(item, schemaType.items);
}))
return false;
}
if (schemaType.enum)
if (!value.every(item => schemaType.enum.includes(item)))
return false;
}
if (schemaType.enum)
if (!schemaType.enum.includes(value))
return false;
if (schemaType.type === 'object' && schemaType.properties) {
if (typeof value !== 'object' || value === null)
return false;
if (!validateSchema(value, schemaType.properties))
return false;
}
}
}
return true;
}
function validateValue(value, schemaType) {
if (typeof schemaType === 'string')
return typeof value === schemaType;
if (Array.isArray(schemaType))
return schemaType.includes(value);
return validateSchema({ value }, { value: schemaType });
}