solutaaliquid
Version:
common utils for javascript. Utils to get the global scope (browser, webworker & co.). Customizable string escaper. Utilitize for objects. Extension at base javascript api (usefull extention like String.hashcode()).
231 lines (194 loc) • 5.76 kB
JavaScript
import ObjectProperty from "./ObjectProperty.js";
const equalArraySet = (a, b) => {
if (a.length !== b.length) return false;
const length = a.length;
for (let i = 0; i < length; i++)
if (!equalPojo(a[i], b[i])) {
//console.log("false");
return false;
}
return true;
};
const equalMap = (a, b) => {
if (a.length !== b.length) return false;
for (const key of a.keys())
if (!equalPojo(a.get(key), b.get(key))) {
//console.log("false");
return false;
}
return true;
};
const equalClasses = (a, b) => {
const clazzA = Object.getPrototypeOf(a);
const clazzB = Object.getPrototypeOf(b);
if (clazzA != clazzB) return false;
if (!clazzA) return true;
const propertiesA = Object.getOwnPropertyNames(clazzA);
const propertiesB = Object.getOwnPropertyNames(clazzB);
if (propertiesA.length !== propertiesB.length) return false;
for (const key of propertiesA) {
const valueA = a[key];
const valueB = b[key];
if (!equalPojo(valueA, valueB)) return false;
}
return true;
};
const equalObject = (a, b) => {
const propertiesA = Object.keys(a);
const propertiesB = Object.keys(b);
if (propertiesA.length !== propertiesB.length) return false;
for (const key of propertiesA) {
const valueA = a[key];
const valueB = b[key];
if (!equalPojo(valueA, valueB)) return false;
}
return true;
};
export const isNullOrUndefined = (object) => {
return object == null || typeof object === "undefined";
};
export const isPrimitive = (object) => {
if (object == null) return true;
const type = typeof object;
switch (type) {
case "number":
case "bigint":
case "boolean":
case "string":
case "undefined":
return true;
}
return false;
};
export const isObject = (object) => {
if(isNullOrUndefined(object))
return false;
return typeof object === "object" && (!object.constructor || object.constructor.name === "Object");
};
/**
* equalPojo -> compares only pojos, array, set, map and primitives
*/
export const equalPojo = (a, b) => {
const nullA = isNullOrUndefined(a);
const nullB = isNullOrUndefined(b);
if (nullA || nullB) return a === b;
if (isPrimitive(a) || isPrimitive(b)) return a === b;
const typeA = typeof a;
const typeB = typeof b;
if (typeA != typeB) return false;
if (typeA === "function") return a === b;
//if (a.constructor !== b.constructor) return false;
//if (a instanceof Array || a instanceof Set) return equalArraySet(a, b);
//if (a instanceof Map) return equalMap(a, b);
return equalObject(a, b) && equalClasses(a, b);
};
/**
* checked if an object a simple object. No Array, Map or something else.
*
* @param aObject:object the object to be testing
*
* @return boolean
*/
export const isPojo = (object) => {
if (!isObject(object)) return false;
for (const key in object) {
const value = object[key];
if (typeof value === "function") return false;
}
return true;
};
/**
* append a propery value to an object. If propery exists its would be converted to an array
*
* @param aKey:string name of property
* @param aData:any property value
* @param aObject:object the object to append the property
*
* @return returns the changed object
*/
export const append = function (aKey, aData, aObject) {
if (typeof aData !== "undefined") {
const property = ObjectProperty.load(aObject, aKey, true);
property.append = aData;
}
return aObject;
};
/**
* merging object into a target object. Its only merge simple object and sub objects. Every other
* value would be replaced by value from the source object.
*
* sample: merge(target, source-1, source-2, ...source-n)
*
* @param target:object the target object to merging into
* @param sources:object
*
* @return object returns the target object
*/
export const merge = function (target, ...sources) {
if (!target) target = {};
for (let source of sources) {
if (isPojo(source)) {
Object.getOwnPropertyNames(source).forEach((key) => {
if (isPojo(target[key])) merge(target[key], source[key]);
else target[key] = source[key];
});
}
}
return target;
};
const buildPropertyFilter = function ({ names, allowed }) {
return (name, value, context) => {
return names.includes(name) === allowed;
};
};
export const filter = function () {
const [data, propFilter, { deep = false, recursive = true, parents = [] } = {}] = arguments;
const result = {};
for (let name in data) {
const value = data[name];
const accept = propFilter(name, value, data);
if (accept && (!deep || value === null || value === undefined)) result[name] = value;
else if (accept && deep) {
const type = typeof value;
if (type !== "object" || value instanceof Array || value instanceof Map || value instanceof Set || value instanceof RegExp || parents.includes[value] || value == data) result[name] = value;
else result[name] = filter(value, propFilter, { deep, recursive, parents: parents.concat(data) });
}
}
return result;
};
export const defValue = (o, name, value) => {
Object.defineProperty(o, name, {
value,
writable: false,
configurable: false,
enumerable: false,
});
};
export const defGet = (o, name, get) => {
Object.defineProperty(o, name, {
get,
configurable: false,
enumerable: false,
});
};
export const defGetSet = (o, name, get, set) => {
Object.defineProperty(o, name, {
get,
set,
configurable: false,
enumerable: false,
});
};
export default {
isNullOrUndefined,
isObject,
equalPojo,
isPojo,
append,
merge,
filter,
buildPropertyFilter,
defValue,
defGet,
defGetSet,
};