UNPKG

@egodigital/egoose

Version:

Helper classes and functions for Node.js 10 or later.

568 lines 16.7 kB
"use strict"; /** * This file is part of the @egodigital/egoose distribution. * Copyright (c) e.GO Digital GmbH, Aachen, Germany (https://www.e-go-digital.com/) * * @egodigital/egoose is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, version 3. * * @egodigital/egoose is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.uuid = exports.utc = exports.toStringSafe = exports.toBooleanSafe = exports.randCharsSync = exports.randChars = exports.parseCommandLine = exports.now = exports.normalizeString = exports.isEmptyString = exports.guid = exports.getAppVersionSync = exports.forEachAsync = exports.exec = exports.createCompletedAction = exports.compareValuesBy = exports.compareValues = exports.cloneObj = exports.asUTC = exports.asMoment = exports.asLocal = exports.asArray = exports.applyFuncFor = void 0; const child_process_1 = require("child_process"); const _ = require("lodash"); const crypto = require("crypto"); const fsExtra = require("fs-extra"); const path = require("path"); const moment = require("moment-timezone"); const util = require("util"); const UUID = require("uuid"); const UUID_v5 = require("uuid/v5"); const yargs = require("yargs-parser"); /** * Applies an object or value to a function. * * @param {TFunc} func The function to apply 'thisArg' to. * @param {any} thisArg The object or value to apply to 'func'. * * @return {TFunc} The new function. */ function applyFuncFor(func, thisArg) { return function () { return func.apply(thisArg, arguments); }; } exports.applyFuncFor = applyFuncFor; /** * Returns an input value as array. * * @param {T|T[]} val The input value. * @param {boolean} [noEmpty] Remove values, which are (null) or (undefined). * * @return {T[]} The input value as array. */ function asArray(val, noEmpty = true) { if (!Array.isArray(val)) { val = [val]; } return val.filter(x => { if (noEmpty) { return !_.isNil(x); } return true; }); } exports.asArray = asArray; /** * Keeps sure that a value is a Moment instance (local timezone). * * @param {any} time The input value. * * @return {moment.Moment} The Moment instance. */ function asLocal(time) { let result = asMoment(time); if (!_.isNil(result)) { if (result.isValid()) { if (!result.isLocal()) { result = result.local(); } } } return result; } exports.asLocal = asLocal; /** * Keeps sure that a value is a Moment instance. * * @param {any} val The input value. * * @return {moment.Moment} The Moment instance. */ function asMoment(val) { if (_.isNil(val)) { return val; } let result; if (moment.isMoment(val)) { result = val; } else if (moment.isDate(val)) { result = moment(val); } else { const TIME_STR = toStringSafe(val).trim(); if (/^([0-9]{1,})$/i.test(TIME_STR)) { // UNIX timestamp result = moment(parseInt(TIME_STR)); } else { result = moment(TIME_STR); } } return result; } exports.asMoment = asMoment; /** * Keeps sure that a value is a Moment instance (UTC timezone). * * @param {any} time The input value. * * @return {moment.Moment} The Moment instance. */ function asUTC(time) { let result = asMoment(time); if (!_.isNil(result)) { if (result.isValid()) { if (!result.isUTC()) { result = result.utc(); } } } return result; } exports.asUTC = asUTC; /** * Clones an object / value. * * @param {T} obj The value to clone. * * @return {T} The cloned value. */ function cloneObj(obj) { if (!obj) { return obj; } return JSON.parse(JSON.stringify(obj)); } exports.cloneObj = cloneObj; /** * Compare to values for sorting. * * @param {any} x The "left" value. * @param {any} y The "right" value. * * @return {number} The sort value. */ function compareValues(x, y) { return compareValuesBy(x, y, i => i); } exports.compareValues = compareValues; /** * Compare to values for sorting by using a selector. * * @param {any} x The "left" value. * @param {any} y The "right" value. * @param {Function} selector The selector. * * @return {number} The sort value. */ function compareValuesBy(x, y, selector) { const VAL_X = selector(x); const VAL_Y = selector(y); if (VAL_X !== VAL_Y) { if (VAL_X < VAL_Y) { return -1; } if (VAL_X > VAL_Y) { return 1; } } return 0; } exports.compareValuesBy = compareValuesBy; /** * Creates a simple 'completed' callback for a promise. * * @param {Function} resolve The 'succeeded' callback. * @param {Function} reject The 'error' callback. * * @return {CompletedAction<TResult>} The created action. */ function createCompletedAction(resolve, reject) { let completedInvoked = false; return (err, result) => { if (completedInvoked) { return; } completedInvoked = true; if (err) { if (reject) { reject(err); } } else { if (resolve) { resolve(result); } } }; } exports.createCompletedAction = createCompletedAction; /** * Promise version of `child_process.exec()` function. * * @param {string} command The command to execute. * * @return {Promise<ExecResult>} The promise with the result. */ async function exec(command) { command = toStringSafe(command); return new Promise((resolve, reject) => { try { child_process_1.exec(command, (err, stdout, stderr) => { if (err) { reject(err); } else { resolve({ stderr: stderr, stdout: stdout, }); } }); } catch (e) { reject(e); } }); } exports.exec = exec; /** * An async 'forEach'. * * @param {Enumerable.Sequence<T>} seq The sequence or array to iterate. * @param {ForEachAsyncAction<T>} action The action to invoke. */ async function forEachAsync(seq, action) { let i = -1; for (const ITEM of seq) { ++i; await Promise.resolve(action(ITEM, i)); } } exports.forEachAsync = forEachAsync; /** * Detects version information about the current app via Git (synchronous). * * @param {GetAppVersionOptions} [opts] Custom options. * * @return {AppVersion} Version information. */ function getAppVersionSync(opts) { if (!opts) { opts = {}; } // working directory let cwd = toStringSafe(opts.cwd); if (isEmptyString(cwd)) { cwd = process.cwd(); } if (!path.isAbsolute(cwd)) { cwd = path.join(process.cwd(), cwd); } cwd = path.resolve(cwd); const VERSION = {}; // VERSION.date try { VERSION.date = asUTC(moment(child_process_1.execSync('git log -n1 --pretty=%cI HEAD', { cwd: cwd, }).toString('utf8') .trim())); } catch { VERSION.date = false; } // VERSION.hash try { VERSION.hash = normalizeString(child_process_1.execSync('git log --pretty="%H" -n1 HEAD', { cwd: cwd, }).toString('utf8')); } catch { VERSION.hash = false; } // VERSION.code try { let buildNr = false; // first check for 'BUILD_NR' file const BUILD_NR_FILE = path.resolve(path.join(cwd, 'BUILD_NR')); if (fsExtra.existsSync(BUILD_NR_FILE)) { // does exist? if (fsExtra.statSync(BUILD_NR_FILE).isFile()) { // check if file buildNr = parseInt(fsExtra.readFileSync(BUILD_NR_FILE, 'utf8') .trim()); } } if (false === buildNr) { // now try from 'BUILD_NR' env var const BUILD_NR = toStringSafe(process.env.BUILD_NR) .trim(); if ('' !== BUILD_NR) { buildNr = parseInt(BUILD_NR); } } if (false !== buildNr) { VERSION.code = isNaN(buildNr) ? false : buildNr; } } catch (e) { VERSION.code = false; } // VERSION.name try { const PACKAGE_JSON_FILE = path.resolve(path.join(cwd, 'package.json')); if (fsExtra.existsSync(PACKAGE_JSON_FILE)) { // does exist? if (fsExtra.statSync(PACKAGE_JSON_FILE).isFile()) { // check if file const PACKAGE_JSON = JSON.parse(fsExtra.readFileSync(PACKAGE_JSON_FILE, 'utf8') .trim()); if (PACKAGE_JSON && !isEmptyString(PACKAGE_JSON.version)) { VERSION.name = toStringSafe(PACKAGE_JSON.version) .trim(); } } } } catch (e) { VERSION.name = false; } return VERSION; } exports.getAppVersionSync = getAppVersionSync; /** * Alias of 'uuid()' function. */ function guid(version) { return uuid.apply(null, arguments); } exports.guid = guid; /** * Checks if the string representation of a value is an empty string or not. * * @param {any} val The value to check. * * @return {boolean} If empty string or not. */ function isEmptyString(val) { return '' === toStringSafe(val) .trim(); } exports.isEmptyString = isEmptyString; /** * Normalizes a value to a string, which is comparable. * * @param {any} val The value to normalize. * * @return {string} The normalized string. */ function normalizeString(val) { return toStringSafe(val).toLowerCase() .trim(); } exports.normalizeString = normalizeString; /** * Returns the current time. * * @param {string} [timezone] The custom timezone to use. * * @return {Moment.Moment} The current time. */ function now(timezone) { timezone = toStringSafe(timezone).trim(); const NOW = moment(); return '' === timezone ? NOW : NOW.tz(timezone); } exports.now = now; /** * Parses a value as string of a command line input. * * @param {any} cmd The command line input. * * @return {ParsedCommandLine} The parsed data. */ function parseCommandLine(cmd) { cmd = toStringSafe(cmd).trim(); const ARGS = yargs(cmd); cmd = normalizeString(ARGS._[0]); ARGS._ = ARGS._.filter((a, i) => i > 0).map((a) => { if (_.isString(a)) { if (a.startsWith('"') && a.endsWith('"')) { a = a.substr(1, a.length - 2); a = a.split('\\"') .join('"'); } } return a; }); if ('' === cmd) { cmd = undefined; } return { arguments: ARGS, command: cmd, }; } exports.parseCommandLine = parseCommandLine; /** * Generates a random string. * * @param {number} size The size of the result string. * @param {string} [chars] The custom list of characters. * * @return {Promise<string>} The promise with the random string. */ async function randChars(size, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') { return randCharsInner(await util.promisify(crypto.randomBytes)(size), chars); } exports.randChars = randChars; function randCharsInner(randBlob, chars) { chars = toStringSafe(chars); let str = ''; for (let i = 0; i < randBlob.length; i++) { str += chars.substr(randBlob.readInt8(i) % chars.length, 1); } return str; } /** * Generates a random string. * * @param {number} size The size of the result string. * @param {string} [chars] The custom list of characters. * * @return {string} The random string. */ function randCharsSync(size, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') { return randCharsInner(crypto.randomBytes(size), chars); } exports.randCharsSync = randCharsSync; /** * Returns a value as "real" boolean. * * @param {any} val The input value. * @param {boolean} [defaultValue] The value to return if 'val' is (null) or (undefined). * * @return {boolean} The output value. */ function toBooleanSafe(val, defaultValue = false) { if (_.isBoolean(val)) { return val; } if (_.isNil(val)) { return !!defaultValue; } return !!val; } exports.toBooleanSafe = toBooleanSafe; /** * Converts a value to a string (if needed), which is not (null) and not (undefined). * * @param {any} val The value to convert. * @param {string} [defaultValue] The custom default value if 'val' is (null) or (undefined). * * @return {string} 'val' as string. */ function toStringSafe(val, defaultValue = '') { if (_.isString(val)) { return val; } if (_.isNil(val)) { return '' + defaultValue; } if (val instanceof Error) { return `[${val.name}] ${val.message}${_.isNil(val.stack) ? '' : ("\n\n" + val.stack)}`; } if (_.isFunction(val['toString'])) { return '' + val.toString(); } if (Array.isArray(val) || _.isObjectLike(val)) { return JSON.stringify(val); } return '' + val; } exports.toStringSafe = toStringSafe; /** * Returns the current time in UTC. * * @return {moment.Moment} The current UTC time. */ function utc() { return moment.utc(); } exports.utc = utc; /** * Generates an unique ID. * * @param {string} [version] The custom version to use. Default: 4 * @param {any[]} [] * * @return {string} The new GUID / unique ID. */ function uuid(version, ...args) { version = normalizeString(version); switch (version) { case '': case '4': case 'v4': return UUID.v4 .apply(null, args); case '1': case 'v1': return UUID.v1 .apply(null, args); case '5': case 'v5': return UUID_v5.apply(null, args); } throw new Error(`Version '${version}' is not supported`); } exports.uuid = uuid; __exportStar(require("./apis/host"), exports); __exportStar(require("./apis/index"), exports); __exportStar(require("./apis/statistics"), exports); __exportStar(require("./apis/validation"), exports); __exportStar(require("./azure/storage"), exports); __exportStar(require("./cache"), exports); __exportStar(require("./cache/redis"), exports); __exportStar(require("./dev"), exports); __exportStar(require("./diagnostics/logger"), exports); __exportStar(require("./diagnostics/stopwatch"), exports); __exportStar(require("./env"), exports); __exportStar(require("./events"), exports); __exportStar(require("./fs"), exports); __exportStar(require("./geo"), exports); __exportStar(require("./http"), exports); __exportStar(require("./http/websockets"), exports); __exportStar(require("./mail"), exports); __exportStar(require("./mongo/index"), exports); __exportStar(require("./mongo/statistics"), exports); __exportStar(require("./oauth/microsoft"), exports); __exportStar(require("./queues/index"), exports); __exportStar(require("./schemas"), exports); __exportStar(require("./services/feedback"), exports); __exportStar(require("./statistics"), exports); __exportStar(require("./streams"), exports); __exportStar(require("./strings"), exports); __exportStar(require("./system"), exports); __exportStar(require("./zip/builder"), exports); var swagger_jsdoc_express_1 = require("swagger-jsdoc-express"); Object.defineProperty(exports, "setupSwaggerUIFromSourceFiles", { enumerable: true, get: function () { return swagger_jsdoc_express_1.setupSwaggerUIFromSourceFiles; } }); //# sourceMappingURL=index.js.map