@stnekroman/tstools
Version:
Set of handy tools for TypeScript development
292 lines (291 loc) • 9.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Objects = void 0;
var Objects;
(function (Objects) {
function isNotNullOrUndefined(arg) {
return arg !== null && arg !== undefined;
}
Objects.isNotNullOrUndefined = isNotNullOrUndefined;
function isNullOrUndefined(arg) {
return arg === null || arg === undefined;
}
Objects.isNullOrUndefined = isNullOrUndefined;
function isObject(arg) {
return typeof arg === 'object' && arg !== null && !Array.isArray(arg);
}
Objects.isObject = isObject;
function isFunction(arg) {
return typeof arg === 'function';
}
Objects.isFunction = isFunction;
function isArray(arg) {
return Array.isArray(arg) || arg instanceof Array;
}
Objects.isArray = isArray;
function isString(arg) {
return typeof arg === 'string';
}
Objects.isString = isString;
function isNumeric(arg) {
if (!Objects.isNotNullOrUndefined(arg)) {
return false;
}
return typeof arg === 'bigint' || (typeof arg === 'number' && !isNaN(arg));
}
Objects.isNumeric = isNumeric;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
Objects.isBoolean = isBoolean;
function isPrimitive(arg) {
if (!Objects.isNotNullOrUndefined(arg)) {
return true;
}
if (Objects.isObject(arg) || Objects.isFunction(arg) || Array.isArray(arg)) {
return false;
}
else {
return true;
}
}
Objects.isPrimitive = isPrimitive;
function forEach(obj, callback) {
for (const key of Objects.keys(obj)) {
callback(key, obj[key]);
}
}
Objects.forEach = forEach;
function isConstructorOf(test, targetClass) {
if (test === targetClass) {
return true;
}
if (Objects.isFunction(test)) {
let prototype = test.prototype;
while (prototype) {
if (prototype instanceof targetClass) {
return true;
}
prototype = prototype.prototype;
}
}
return false;
}
Objects.isConstructorOf = isConstructorOf;
function equals(obj1, obj2) {
if (obj1 === obj2) {
return true;
}
if (!obj1 || !obj2) {
return false;
}
if (typeof obj1 !== typeof obj2) {
return false;
}
if (Array.isArray(obj1) && Array.isArray(obj2)) {
if (obj1.length !== obj2.length) {
return false;
}
for (let i = 0; i < obj1.length; i++) {
if (!Objects.equals(obj1[i], obj2[i])) {
return false;
}
}
return true;
}
if (Objects.isObject(obj1) && Objects.isObject(obj2)) {
const proto1 = Object.getPrototypeOf(obj1);
const proto2 = Object.getPrototypeOf(obj2);
if (proto1 !== proto2) {
return false;
}
const keys1 = Objects.keys(obj1);
const keys2 = Objects.keys(obj2);
if (keys1.length !== keys2.length) {
return false;
}
if (proto1 === Date.prototype && proto2 === Date.prototype && obj1 instanceof Date && obj2 instanceof Date) {
return obj1.getTime() === obj2.getTime();
}
if (proto1 === RegExp.prototype &&
proto2 === RegExp.prototype &&
obj1 instanceof RegExp &&
obj2 instanceof RegExp) {
return obj1.source === obj2.source && obj1.flags === obj2.flags;
}
const keys2set = new Set(keys2);
for (const key of keys1) {
if (!Objects.equals(obj1[key], obj2[key])) {
return false;
}
keys2set.delete(key);
}
return keys2set.size === 0;
}
return false;
}
Objects.equals = equals;
function keys(obj) {
return Object.keys(obj);
}
Objects.keys = keys;
function assign(target, source) {
return Object.assign(target, source);
}
Objects.assign = assign;
function deepCopy(obj, transferNotCopyable) {
if (Objects.isPrimitive(obj)) {
return obj;
}
if (obj instanceof Date) {
const date = new Date();
date.setTime(obj.getTime());
return date;
}
if (Array.isArray(obj)) {
return obj.map((item) => deepCopy(item, transferNotCopyable));
}
if (Objects.isObject(obj)) {
const copy = {};
Objects.forEach(obj, (key, value) => {
copy[key] = Objects.deepCopy(value, transferNotCopyable);
});
return copy;
}
if (transferNotCopyable) {
return obj;
}
else {
throw new Error('Cannot clone not-copyable fields (methods inside?) during Objects.deepCopy.');
}
}
Objects.deepCopy = deepCopy;
function extend(dst, src, options) {
const canOverwrite = options?.canOverwrite ?? (() => true);
let changed = false;
if (Objects.isNotNullOrUndefined(src)) {
Objects.forEach(src, (key, value) => {
if (Objects.isObject(value) && Objects.isObject(dst[key])) {
changed ||= Objects.extend(dst[key], value);
}
else {
const overwrite = canOverwrite(dst, src, key);
if (overwrite) {
dst[key] = Objects.deepCopy(src[key], true);
}
changed ||= overwrite;
}
});
}
return changed;
}
Objects.extend = extend;
function isCharacterWhitespace(c) {
return (c === ' ' ||
c === '\n' ||
c === '\t' ||
c === '\r' ||
c === '\f' ||
c === '\v' ||
c === '\u00a0' ||
c === '\u1680' ||
c === '\u2000' ||
c === '\u200a' ||
c === '\u2028' ||
c === '\u2029' ||
c === '\u202f' ||
c === '\u205f' ||
c === '\u3000' ||
c === '\ufeff');
}
Objects.isCharacterWhitespace = isCharacterWhitespace;
function isBlankString(str) {
if (Objects.isNotNullOrUndefined(str)) {
for (const ch of str) {
if (!Objects.isCharacterWhitespace(ch)) {
return false;
}
}
}
return true;
}
Objects.isBlankString = isBlankString;
function visit(obj, visitor) {
visitLevel(obj, visitor);
}
Objects.visit = visit;
function visitLevel(obj, visitor, seen = new Set(), level = 0) {
if (seen.has(obj)) {
return;
}
const children = visitor(obj, level);
seen.add(obj);
if (children) {
for (const child of children) {
visitLevel(child, visitor, seen, level + 1);
}
}
}
function flatten(obj, childrenExtractor) {
const array = [];
visit(obj, (obj, level) => {
array.push(obj);
return childrenExtractor(obj, level);
});
return array;
}
Objects.flatten = flatten;
function setPrototypeOf(target, proto) {
return Object.setPrototypeOf(target, proto);
}
Objects.setPrototypeOf = setPrototypeOf;
function deepFreeze(obj) {
visit(obj, (currentObj) => {
if (!currentObj) {
return void 0;
}
Object.freeze(currentObj);
if (Array.isArray(currentObj)) {
return currentObj;
}
if (typeof currentObj === 'object' && currentObj !== null) {
return Object.values(currentObj);
}
return void 0;
});
return obj;
}
Objects.deepFreeze = deepFreeze;
function getKeyByValue(enumObj, enumValue) {
const keys = Objects.keys(enumObj).filter((k) => enumObj[k] === enumValue);
return keys.length > 0 ? keys[0] : undefined;
}
Objects.getKeyByValue = getKeyByValue;
function transform(obj, mapper) {
const result = {};
for (const key of Objects.keys(obj)) {
const mapped = mapper(key, obj[key]);
if (mapped) {
const [newKey, newValue] = mapped;
result[newKey] = newValue;
}
}
return result;
}
Objects.transform = transform;
function difference(object, base) {
return transform(object, (key, value) => {
const baseValue = base[key];
if (!equals(value, baseValue)) {
if (isObject(value) && isObject(baseValue)) {
return [key, difference(value, baseValue)];
}
else {
return [key, value];
}
}
return;
});
}
Objects.difference = difference;
})(Objects || (exports.Objects = Objects = {}));