@decaf-ts/decorator-validation
Version:
simple decorator based validation engine
133 lines • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hashing = exports.DefaultHashingMethod = void 0;
exports.hashCode = hashCode;
exports.hashObj = hashObj;
/**
* @summary Mimics Java's String's Hash implementation
*
* @param {string | number | symbol | Date} obj
* @return {number} hash value of obj
*
* @function hashCode
* @memberOf module:decorator-validation
* @category Model
*/
function hashCode(obj) {
obj = String(obj);
let hash = 0;
for (let i = 0; i < obj.length; i++) {
const character = obj.charCodeAt(i);
hash = (hash << 5) - hash + character;
hash = hash & hash; // Convert to 32bit integer
}
return hash.toString();
}
/**
* @summary Hashes an object by combining the hash of all its properties
*
* @param {Record<string, any>} obj
* @return {string} the resulting hash
*
* @function hashObj
* @memberOf module:decorator-validation
* @category Model
*/
function hashObj(obj) {
const hashReducer = function (h, el) {
const elHash = hashFunction(el);
if (typeof elHash === "string")
return hashFunction((h || "") + hashFunction(el));
h = h || 0;
h = (h << 5) - h + elHash;
return h & h;
};
const func = hashCode;
const hashFunction = function (value) {
if (typeof value === "undefined")
return "";
if (["string", "number", "symbol"].indexOf(typeof value) !== -1)
return func(value.toString());
if (value instanceof Date)
return func(value.getTime());
if (Array.isArray(value))
return value.reduce(hashReducer, undefined);
return Object.values(value).reduce(hashReducer, undefined);
};
const result = Object.values(obj).reduce(hashReducer, 0);
return (typeof result === "number" ? Math.abs(result) : result).toString();
}
exports.DefaultHashingMethod = "default";
/**
* @description Manages hashing methods and provides a unified hashing interface
* @summary A utility class that provides a registry for different hashing functions and methods to hash objects.
* The class maintains a cache of registered hashing functions and allows setting a default hashing method.
* It prevents direct instantiation and provides static methods for registration and hashing.
*
* @class Hashing
* @category Model
*
* @example
* ```typescript
* // Register a custom hashing function
* Hashing.register('md5', (obj) => createMD5Hash(obj), true);
*
* // Hash an object using default method
* const hash1 = Hashing.hash(myObject);
*
* // Hash using specific method
* const hash2 = Hashing.hash(myObject, 'md5');
* ```
*/
class Hashing {
/**
* @description Current default hashing method identifier
* @private
*/
static { this.current = exports.DefaultHashingMethod; }
/**
* @description Cache of registered hashing functions
* @private
*/
static { this.cache = {
default: hashObj,
}; }
constructor() { }
/**
* @description Retrieves a registered hashing function
* @summary Fetches a hashing function from the cache by its key. Throws an error if the method is not registered.
*
* @param {string} key - The identifier of the hashing function to retrieve
* @return {HashingFunction} The requested hashing function
* @private
*/
static get(key) {
if (key in this.cache)
return this.cache[key];
throw new Error(`No hashing method registered under ${key}`);
}
/**
* @description Registers a new hashing function
* @summary Adds a new hashing function to the registry. Optionally sets it as the default method.
* Throws an error if a method with the same key is already registered.
*
* @param {string} key - The identifier for the hashing function
*/
static register(key, func, setDefault = false) {
if (key in this.cache)
throw new Error(`Hashing method ${key} already registered`);
this.cache[key] = func;
if (setDefault)
this.current = key;
}
static hash(obj, method, ...args) {
if (!method)
return this.get(this.current)(obj, ...args);
return this.get(method)(obj, ...args);
}
static setDefault(method) {
this.current = this.get(method);
}
}
exports.Hashing = Hashing;
//# sourceMappingURL=hashing.js.map