UNPKG

larvitutils

Version:
270 lines (269 loc) 9.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Log = exports.Utils = void 0; const topLogPrefix = 'larvitutils: src/index.ts: '; class Log { /** * Simple logging instance * * @param options[=process.env.NODE_LOG_LVL] - Optional options object or minimum log level * @param options.level[=process.env.NODE_LOG_LVL] - log level */ constructor(options) { this.validLogLevels = ['silly', 'debug', 'verbose', 'info', 'warn', 'error', 'none']; const defaultLogLevel = this.getDefaultLogLevel(); if (this.isLogLevel(options)) { this.options = { level: options }; } else if (this.optionsIsLogOptions(options)) { if (!this.isLogLevel(options.level)) { this.options = { level: defaultLogLevel }; } else { this.options = { level: options.level }; } } else { this.options = { level: defaultLogLevel }; } } frmtStr(lvl, msg, metadata) { let str = `${(new Date()).toISOString().substring(0, 19)}Z [${lvl}] ${msg}`; if (metadata) { str += ` ${JSON.stringify(metadata)}`; } return str; } stdout(lvl, msg, metadata) { // tslint:disable-next-line:no-console console.log(this.frmtStr(lvl, msg, metadata)); } stderr(lvl, msg, metadata) { // tslint:disable-next-line:no-console console.error(this.frmtStr(lvl, msg, metadata)); } silly(msg, metadata) { if (this.options.level === 'silly') { this.stdout('\x1b[1;37msil\x1b[0m', msg, metadata); } } debug(msg, metadata) { if (['silly', 'debug'].includes(this.options.level)) { this.stdout('\x1b[1;35mdeb\x1b[0m', msg, metadata); } } verbose(msg, metadata) { if (['silly', 'debug', 'verbose'].includes(this.options.level)) { this.stdout('\x1b[1;34mver\x1b[0m', msg, metadata); } } info(msg, metadata) { if (['silly', 'debug', 'verbose', 'info'].includes(this.options.level)) { this.stdout('\x1b[1;32minf\x1b[0m', msg, metadata); } } warn(msg, metadata) { if (['silly', 'debug', 'verbose', 'info', 'warn'].includes(this.options.level)) { this.stderr('\x1b[1;33mwar\x1b[0m', msg, metadata); } } error(msg, metadata) { if (['silly', 'debug', 'verbose', 'info', 'warn', 'error'].includes(this.options.level)) { this.stderr('\x1b[1;31merr\x1b[0m', msg, metadata); } } getDefaultLogLevel() { if (typeof process === 'undefined' || !process || !process.env || !process.env.NODE_LOG_LVL) { return 'info'; } else if (this.validLogLevels.includes(process.env.NODE_LOG_LVL || '')) { return process.env.NODE_LOG_LVL; } else { return 'info'; } } optionsIsLogOptions(options) { if (options === undefined || typeof options !== 'object') { return false; } else { return true; } } isLogLevel(options) { if (options === undefined) { return false; } for (let i = 0; this.validLogLevels.length !== i; i++) { if (this.validLogLevels[i] === options) { return true; } } return false; } } exports.Log = Log; class Utils { constructor(options) { this.Log = Log; this.options = options || {}; if (this.isLogInstance(this.options.log)) { this.log = this.options.log; } else { this.log = this.options.log = new Log(); } } getUniqueCombinations(keyValues) { const response = []; function addUniqueCombination(curKeyVals, subKeyValues) { const workSubKeyValuesName = Object.keys(subKeyValues)[Object.keys(curKeyVals).length]; const workSubKeyValues = subKeyValues[workSubKeyValuesName]; // If this is the last key val to look for, loop through them all, add them and return them if (Object.keys(curKeyVals).length === Object.keys(subKeyValues).length) { response.push(curKeyVals); // Loop through next key in line } else { for (let i = 0; workSubKeyValues.length !== i; i++) { const nextKeyVal = Object.assign({}, curKeyVals); const workSubKeyValue = workSubKeyValues[i]; nextKeyVal[workSubKeyValuesName] = workSubKeyValue; addUniqueCombination(nextKeyVal, subKeyValues); } } } if (Object.keys(keyValues).length === 0) { return response; } // Initiate the getter by calling addUniqueCombination() for each value on the first key const firstKeyValuesName = Object.keys(keyValues)[0]; const firstKeyValues = keyValues[firstKeyValuesName]; for (let i = 0; firstKeyValues.length !== i; i++) { const firstKeyValue = firstKeyValues[i]; const initKeyValList = {}; initKeyValList[firstKeyValuesName] = firstKeyValue; addUniqueCombination(initKeyValList, keyValues); } return response; } /** * Convert hrtime diff to milliseconds * * @param prevTime the output from process.hrtime() to diff to * @param precision defaults to 2, must be an exact integer * @return time diff in milliseconds rounded to given precision */ hrtimeToMs(prevTime, precision) { const diff = process.hrtime(prevTime); if (precision === undefined) { precision = 2; } return ((diff[0] * 1000) + (diff[1] / 1000000)).toFixed(precision); } escapeRegExp(str) { return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1'); } /** * Formats an uuid string * * For example adds missing "-", trimming spaces etc * * @param uuidStr Can also take a buffer * @return uuid string or false on failure */ formatUuid(uuidStr) { // If a buffer, get the string representation if (Buffer.isBuffer(uuidStr)) { uuidStr = uuidStr.toString('hex'); } // Now uuidStr MUST be a string if (typeof uuidStr !== 'string') { return false; } // Remove all but hex characters uuidStr = uuidStr.replace(/[^A-Fa-f0-9]/g, '').toLowerCase(); // All uuid strings have exactly 32 hex characters! if (uuidStr.length !== 32) { return false; } // Add dashes in the right places let returnStr = ''; returnStr = uuidStr.substring(0, 8); returnStr += '-' + uuidStr.substring(8, 12); returnStr += '-' + uuidStr.substring(12, 16); returnStr += '-' + uuidStr.substring(16, 20); returnStr += '-' + uuidStr.substring(20); return returnStr; } /** * Replace all occurances of a string in a string and return the result * * @param search What to search for * @param {string} replace What to replace it with * @param {string} str The string to perform this to * @return {string} The result */ replaceAll(search, replace, str) { return str.replace(new RegExp(this.escapeRegExp(search), 'g'), replace); } async setTimeout(ms) { return new Promise(resolve => { setTimeout(() => resolve(), ms); }); } /** * Make a buffer from an uuid string * * @param uuidStr Can be with or without dashes, padded spaces etc will be trimmed * @return or false on fail */ uuidToBuffer(uuidStr) { const logPrefix = topLogPrefix + 'uuidToBuffer() - '; const { log } = this; if (typeof uuidStr !== 'string') { const stack = new Error().stack; log.warn(logPrefix + 'uuidStr is not a string, but a ' + (typeof uuidStr)); log.verbose(logPrefix + stack); return false; } // Remove all but hex characters uuidStr = uuidStr.replace(/[^A-Fa-f0-9]/g, ''); // All uuid strings have exactly 32 hex characters! if (uuidStr.length !== 32) { const stack = new Error().stack; log.warn(logPrefix + 'uuidStr should be exactly 32 characters after regex, but is: ' + uuidStr.length); log.verbose(logPrefix + stack); return false; } return Buffer.from(uuidStr, 'hex'); } /** * Check if input is an int * * @param value The value to check * @return boolean */ isInt(value) { const x = parseFloat(value); if (isNaN(value)) { return false; } return (x | 0) === x; } isLogInstance(logInstance) { if (typeof logInstance === 'object') { if (typeof logInstance.silly === 'function' && typeof logInstance.debug === 'function' && typeof logInstance.verbose === 'function' && typeof logInstance.info === 'function' && typeof logInstance.warn === 'function' && typeof logInstance.error === 'function') { return true; } } return false; } } exports.Utils = Utils;