UNPKG

@cisstech/nge

Version:

NG Essentials is a collection of libraries for Angular developers.

486 lines (476 loc) 16 kB
function deepCopy(obj) { if (obj === null || typeof obj !== 'object') { return obj; } const copy = obj instanceof Array ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { ; copy[key] = deepCopy(obj[key]); } } return copy; } class Serializer { static serialize(instance) { const record = {}; const prototype = instance.constructor.prototype; const properties = prototype.__properties_infos__; Object.keys(properties).forEach((propertyName) => { if (!(propertyName in instance)) { return; } const property = properties[propertyName]; const exportName = (property.aliases ?? []).pop() ?? propertyName; const value = instance[propertyName]; if (value == null) { return; } switch (typeof value) { case 'string': case 'number': case 'boolean': if (value != null) { record[exportName] = value; } break; case 'object': if (property.type) { if (Array.isArray(value)) { record[exportName] = value .map((e) => { return Serializer.serialize(e); }) .filter((e) => e != null); } else if (property.indexed) { record[exportName] = Object.keys(value).reduce((obj, key) => { if (value[key] === undefined) { return obj; } obj[key] = Serializer.serialize(value[key]); return obj; }, {}); } else { record[exportName] = Serializer.serialize(value); } } else { if (Array.isArray(value)) { record[exportName] = value.filter((obj) => obj != null); } else { record[exportName] = deepCopy(value); } } break; } }); return record; } static deserialize(target, props) { const record = { ...props, }; const prototype = target.prototype; const info = prototype.__class_info__; if (info.resolver) { target = info.resolver(props); } const properties = prototype.__properties_infos__; Object.keys(properties).forEach((propertyName) => { const property = properties[propertyName]; const aliases = property.aliases ?? []; const value = props[propertyName] ?? Object.keys(props).find((k) => { return !!aliases.find((alias) => alias === k); }); if (value == null) { return; } switch (typeof value) { case 'object': if (property.type) { if (Array.isArray(value)) { record[propertyName] = value.map((e) => { return Serializer.deserialize(property.type, e); }); } else if (property.indexed) { Object.keys(value).forEach((k) => { value[k] = Serializer.deserialize(property.type, value[k]); }); record[propertyName] = value; } else { record[propertyName] = Serializer.deserialize(property.type, value); } } else { record[propertyName] = value; } break; default: record[propertyName] = value; break; } }); return new target(record); } } class Builder { /** * Creates new instance of `T` class. * @param props properties to pass to the constructor of the instance. * @returns new instance of `T` */ // eslint-disable-next-line @typescript-eslint/no-unused-vars static create(props) { throw new Error('This is an abstract method. It needs to be overridden.'); } save() { throw new Error('This is an abstract method. It needs to be overridden.'); } // eslint-disable-next-line @typescript-eslint/no-unused-vars with(props) { throw new Error('This is an abstract method. It needs to be overridden.'); } } function Entity(info) { return function (target) { const prototype = target.prototype; info = info ?? {}; prototype.__class_info__ = prototype.__class_info__ ?? info; prototype.__class_info__ = { ...prototype.__class_info__, ...info, }; prototype.save = function () { return Serializer.serialize(this); }; prototype.with = function (props) { return new target({ ...this, ...props, }); }; target.create = function (props) { return Serializer.deserialize(target, props); }; return target; }; } function Property(info) { return (instance, name) => { info = info ?? { aliases: [], }; const prototype = instance.constructor.prototype; prototype.__properties_infos__ = prototype.__properties_infos__ ?? {}; prototype.__properties_infos__[name] = info; }; } function rgbFromHex(color) { color = color.replace('#', ''); const n = color.length; if (n == 3) { // convert rgb to rrggbb const r = color[0]; const g = color[1]; const b = color[2]; color = `${r}${r}${g}${g}${b}${b}`; } const rgb = parseInt(color, 16); // convert rrggbb to decimal return { r: (rgb >> 16) & 0xff, // extract red g: (rgb >> 8) & 0xff, // extract green b: (rgb >> 0) & 0xff, // extract blue }; } function rgbToHex(r, g, b) { r = Math.round(r); g = Math.round(g); b = Math.round(b); const componentToHex = (c) => { const hex = c.toString(16); return hex.length == 1 ? '0' + hex : hex; }; return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b); } function colorContrast(color) { const { r, g, b } = rgbFromHex(color); const contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000; return contrast >= 128 ? 'black' : 'white'; } // https://maketintsandshades.com/about function colorTint(color, factor = 0.1 /* 10% */) { let { r, g, b } = rgbFromHex(color); r += (255 - r) * factor; g += (255 - g) * factor; b += (255 - b) * factor; return rgbToHex(r, g, b); } function colorShade(color, factor = 0.88 /* 12% */) { let { r, g, b } = rgbFromHex(color); r *= factor; g *= factor; b *= factor; return rgbToHex(r, g, b); } function deepEqual(a, b) { if (a === b) return true; if (a && b && typeof a == 'object' && typeof b == 'object') { if (a.constructor !== b.constructor) return false; var length, i, keys; if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; for (i = length; i-- !== 0;) if (!deepEqual(a[i], b[i])) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys = Object.keys(a); length = keys.length; if (length !== Object.keys(b).length) return false; for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = length; i-- !== 0;) { var key = keys[i]; if (!deepEqual(a[key], b[key])) return false; } return true; } // true if both NaN, false otherwise return a !== a && b !== b; } function ensuresNonNull(value, message) { if (value == null) { throw new ReferenceError(message); } return true; } function ensuresNonNullArray(value, message) { if (value == null) { throw new ReferenceError(message); } value.forEach((v) => { if (v == null) { throw ReferenceError(message); } }); return true; } function ensuresNonNullString(value, message) { if (value == null || value.trim().length === 0) { message = message || `'require non null|empty string`; throw new ReferenceError(message); } return true; } function ensures(condition, message) { if (!condition) { throw new Error(message); } } function epoch() { return new Date('01/01/1970'); } function addDays(date, days) { date = new Date(date.valueOf()); date.setDate(date.getDate() + days); return date; } /** Gets current value of unix timestamp */ function timestamp() { return new Date().getTime() / 1000; } /** * Gets unix timestamp value of `date` * @param date the date. */ function toTimestamp(date) { return date.getTime() / 1000; } /** * Converts an unix timestamp to a Date object * @param time an unix timestamp */ function dateFromTimestamp(time) { return new Date(time * 1000); } /** * Converts an unix timestamp to a date in the format 'day month hours mins' * @param time an unix timestamp. * @param locale target language locale tag. * @returns string representation of the date. */ function fullDate(time, locale) { const format = { month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', }; return convertDate(time, format, locale); } /** * Converts an unix timestamp to a date in the format 'day month' * @param time an unix timestamp. * @param locale target language locale tag. * @returns string representation of the date. */ function shortDate(time, locale) { return convertDate(time, { month: 'short', day: 'numeric' }, locale); } /** * Converts an unix timestamp to a date in the format 'hours mins' * @param time an unix timestamp. * @returns string representation of the date. */ function hours(time) { const date = dateFromTimestamp(time); const minutes = date.getMinutes(); const minutesFormat = minutes >= 10 ? minutes : `0${minutes}`; return `${date.getHours()}:${minutesFormat}`; } /** * Gets a value indicating whether the timestamp is today. * @param time an unix timestamp. */ function isToday(time) { return new Date().toLocaleDateString() === dateFromTimestamp(time).toLocaleDateString(); } /** * Gets a value indicating whether the given dates representes the same year, month and day. * @param d1 the first date. * @param d2 the second date. */ function compareDays(d1, d2) { return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate(); } function convertDate(time, format, locale) { const date = dateFromTimestamp(time); return date.toLocaleDateString(locale, format); } function weeksDiff(d1, d2) { let diff = (d2.getTime() - d1.getTime()) / 1000; diff /= 60 * 60 * 24 * 7; return Math.abs(Math.round(diff)); } function dateRangeOverlaps(a_start, a_end, b_start, b_end) { if (a_start < b_start && b_start < a_end) return true; // b starts in a if (a_start < b_end && b_end < a_end) return true; // b ends in a if (b_start < a_start && a_end < b_end) return true; // a in b return false; } function isImage(extension) { extension = extension.toLowerCase(); if (!extension.startsWith('.')) { extension = '.' + extension; } return ['.ai', '.png', '.jpg', '.pjg', '.gif', '.svg', '.jpeg'].includes(extension); } function isPdf(extension) { extension = extension.toLowerCase(); if (!extension.startsWith('.')) { extension = '.' + extension; } return extension === '.pdf'; } function isWordDoc(extension) { extension = extension.toLowerCase(); if (!extension.startsWith('.')) { extension = '.' + extension; } return ['.odt', '.doc', '.docx'].includes(extension); } function isText(extension) { extension = extension.toLowerCase(); return extension === 'txt' || extension === '.txt'; } function isExcelDoc(extension) { extension = extension.toLowerCase(); if (!extension.startsWith('.')) { extension = '.' + extension; } return ['.xlsx', '.xlsm', '.xsl', '.xst'].includes(extension); } function isPowerPointDoc(extension) { extension = extension.toLowerCase(); if (!extension.startsWith('.')) { extension = '.' + extension; } return ['.ppt', '.pptm', '.pptx'].includes(extension); } /** * Gets the extension of the file (without the dot '.'). * Throws an exception if the file is undefined. * @param file the file * @returns the extension of the file. */ function extensionOf(file) { if (file instanceof File) { const tmp1 = Math.max(0, file.name.lastIndexOf('.')); return file.name.slice((tmp1 || Infinity) + 1).toLowerCase(); } const tmp2 = Math.max(0, file.type.lastIndexOf('/')); return file.type.slice((tmp2 || Infinity) + 1).toLowerCase(); } function isNullOrEmpty(text) { return text == null || text.trim() === ''; } function anyNullOrEmpty(...args) { if (args == null) { return true; } for (const e of args) { if (isNullOrEmpty(e)) { return true; } } return false; } const urlPattern = '^(https?:\\/\\/)?' + // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address '(\\:\\d+)?(\\/[@-a-z\\d%_.~+]*)*' + // port and path '(\\?[;@&a-z\\d%_.~+=-]*)?' + // query string '(\\#[@-a-z\\d_]*)?$'; function isURL(str) { // https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url const pattern = new RegExp(urlPattern, 'i'); // fragment locator return !!pattern.test(str); } function hashCode(str) { let hash = 0; if (str.length === 0) return hash; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; // Convert to 32bit integer } return hash; } /** * Generated bundle index. Do not edit. */ export { Builder, Entity, Property, addDays, anyNullOrEmpty, colorContrast, colorShade, colorTint, compareDays, convertDate, dateFromTimestamp, dateRangeOverlaps, deepCopy, deepEqual, ensures, ensuresNonNull, ensuresNonNullArray, ensuresNonNullString, epoch, extensionOf, fullDate, hashCode, hours, isExcelDoc, isImage, isNullOrEmpty, isPdf, isPowerPointDoc, isText, isToday, isURL, isWordDoc, rgbFromHex, rgbToHex, shortDate, timestamp, toTimestamp, urlPattern, weeksDiff }; //# sourceMappingURL=cisstech-nge-utils.mjs.map