UNPKG

@uploadx/core

Version:
186 lines (185 loc) 5.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toBoolean = exports.hash = exports.memoize = exports.uid = exports.pick = void 0; exports.md5 = md5; exports.fnv = fnv; exports.fnv64 = fnv64; exports.mapValues = mapValues; exports.isEqual = isEqual; exports.isNumber = isNumber; exports.isRecord = isRecord; exports.extendObject = extendObject; exports.toMilliseconds = toMilliseconds; exports.toSeconds = toSeconds; exports.getFirstOne = getFirstOne; exports.getLastOne = getLastOne; exports.durationToMs = durationToMs; const crypto_1 = require("crypto"); const util_1 = require("util"); const cache_1 = require("./cache"); const pick = (obj, whitelist) => { const result = {}; whitelist.forEach(key => (result[key] = obj[key])); return result; }; exports.pick = pick; const uid = () => (0, crypto_1.randomBytes)(16).toString('hex'); exports.uid = uid; function md5(str) { return (0, crypto_1.createHash)('md5').update(str).digest('hex'); } /** * FNV1A32 hash */ function fnv(str) { let hash = 2166136261; const bytes = Buffer.from(str, 'utf8'); for (const byte of bytes) { hash ^= byte; hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); } return (hash >>> 0).toString(16); } /** * FNV1A64 hash */ function fnv64(str) { let hash = 14695981039346656037n; const offset = 1099511628211n; const bytes = Buffer.from(str, 'utf8'); for (const byte of bytes) { hash ^= BigInt(byte); hash = BigInt.asUintN(64, hash * offset); } return hash.toString(16); } function mapValues(object, func) { const result = {}; const keys = Object.keys(object); for (const key of keys) { result[key] = func(object[key]); } return result; } function isEqual(a, b, ...keysToIgnore) { return (0, util_1.isDeepStrictEqual)(Object.entries(a).filter(e => !keysToIgnore.includes(e[0])), Object.entries(b).filter(e => !keysToIgnore.includes(e[0]))); } function isNumber(x) { return x === Number(x); } function isRecord(x) { // return Object.prototype.toString.call(x) === '[object Object]'; return x !== null && typeof x === 'object' && !Array.isArray(x); } function extendObject(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isRecord(source)) { for (const key in source) { if (isRecord(source[key])) { if (!isRecord(target[key])) Object.assign(target, { [key]: {} }); extendObject(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return extendObject(target, ...sources); } /** * Convert a human-readable duration to ms */ function toMilliseconds(value) { if (isNumber(value)) return value; if (!value) return undefined; return durationToMs(value) || undefined; } /** * Convert a human-readable duration to seconds */ function toSeconds(value) { if (isNumber(value)) return value; const s = Math.floor(durationToMs(value) / 1000) || undefined; return s ? ~~s : s; } /** * Returns a first element of an array */ function getFirstOne(val) { return val[0]; } /** * Returns a last element of an array */ function getLastOne(val) { return val[val.length - 1]; } /** * Returns a function that caches the result of func * @param fn - function to be called */ const memoize = (fn) => { const cache = new cache_1.Cache(1000); return (arg) => { const key = JSON.stringify(arg); let result = cache.get(key); if (result === undefined && !cache.has(key)) { result = fn(arg); cache.set(key, result); } return result; }; }; exports.memoize = memoize; exports.hash = (0, exports.memoize)(fnv64); const toBoolean = (val) => { return ['true', '1', 'y', 'yes'].includes(String(val).trim().toLowerCase()); }; exports.toBoolean = toBoolean; function durationToMs(input) { if (input.length > 50) { throw new Error('Input string exceeds maximum length of 50 characters'); } const durationRegex = /(\d+)\s*([a-zA-Z]+)/g; const matches = Array.from(input.matchAll(durationRegex)); if (matches.length === 0) { throw new Error('Invalid duration format'); } const matchedString = matches.map(match => match[0]).join(''); if (matchedString.replace(/\s+/g, '') !== input.replace(/\s+/g, '')) { throw new Error('Invalid duration format'); } const unitMultipliers = { s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000, M: 2592000000, // 30 days y: 31536000000 // 365 days }; let totalMs = 0; for (const match of matches) { const value = parseInt(match[1], 10); const unit = match[2]; let key; if (unit === 'M' || unit.toLowerCase().startsWith('mo')) { key = 'M'; } else { key = unit[0].toLowerCase(); } const multiplier = unitMultipliers[key]; if (!multiplier) { throw new Error(`Invalid time unit: ${unit}`); } totalMs += value * multiplier; } return totalMs; }