UNPKG

@rzl-zone/utils-js

Version:

A modern, lightweight set of JavaScript utility functions with TypeScript support for everyday development, crafted to enhance code readability and maintainability.

309 lines (301 loc) 12.2 kB
/*! * ==================================================== * Rzl Utils-JS. * ---------------------------------------------------- * Version: 3.11.0. * Author: Rizalvin Dwiky. * Repository: https://github.com/rzl-zone/utils-js. * ==================================================== */ 'use strict'; var chunkDVMHRLKP_cjs = require('./chunk-DVMHRLKP.cjs'); var chunkDAPAK2W3_cjs = require('./chunk-DAPAK2W3.cjs'); var chunkSYHPSOUU_cjs = require('./chunk-SYHPSOUU.cjs'); function getRandomItem(array) { if (!chunkSYHPSOUU_cjs.isNonEmptyArray(array)) return void 0; const randomIndex = Math.floor(Math.random() * (array.length || 0)); return array[randomIndex]; } var randomInt = (min, max) => { if (!chunkDVMHRLKP_cjs.isInteger(min) || !chunkDVMHRLKP_cjs.isInteger(max)) { throw new TypeError( `First parameter (\`min\`) and second parameter (\`max\`) must be of type \`integer-number\`${minValueNote( min, max )}value, but received: ['min': \`${chunkSYHPSOUU_cjs.getPreciseType( min )}\` - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(min, { keepUndefined: true })})\`, 'max': \`${chunkSYHPSOUU_cjs.getPreciseType(max)}\` - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify( max, { keepUndefined: true } )}\`)].` ); } if (min > max) { throw new RangeError( `First parameter (\`min\`) must be less than or equal to second parameter (\`max\`), but received: ['min': ${formatValue( min )} - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(min, { keepUndefined: true })})\`, 'max': ${formatValue(max)} - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(max, { keepUndefined: true })})\`].` ); } min = Math.max(1, min); max = Math.min(Number.MAX_SAFE_INTEGER, max); return Math.floor(Math.random() * (max - min + 1)) + min; }; var formatValue = (value) => { return chunkSYHPSOUU_cjs.isNumber(value, { includeNaN: true }) ? value === Number.MIN_VALUE ? "`Number.MIN_VALUE`" : `${value}` : `\`${chunkSYHPSOUU_cjs.getPreciseType(value)}\``; }; var minValueNote = (...values) => { return values.some((v) => chunkSYHPSOUU_cjs.isNumber(v, { includeNaN: true }) && v === Number.MIN_VALUE) ? " and can't be `Number.MIN_VALUE` " : " "; }; var randomIntByLength = (options) => { if (!chunkSYHPSOUU_cjs.isPlainObject(options)) { options = {}; } const { minLength = 1, maxLength = 16, avoidZero = false } = options; chunkSYHPSOUU_cjs.assertIsBoolean(avoidZero, { message({ currentType, validType }) { return `Parameters \`avoidZero\` must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); if (!chunkDVMHRLKP_cjs.isInteger(minLength) || !chunkDVMHRLKP_cjs.isInteger(maxLength)) { throw new TypeError( `Parameters \`minLength\` and \`maxLength\` must be of type \`integer-number\`, but received: ['minLength': \`${chunkSYHPSOUU_cjs.getPreciseType( minLength )}\` - (with value: ${chunkDAPAK2W3_cjs.safeStableStringify(minLength, { keepUndefined: true })}), 'maxLength': \`${chunkSYHPSOUU_cjs.getPreciseType( maxLength )}\` - (with value: ${chunkDAPAK2W3_cjs.safeStableStringify(maxLength, { keepUndefined: true })})].` ); } if (minLength < 1 || maxLength > 16 || minLength > maxLength) { throw new RangeError( `Invalid range at parameters \`minLength\` must be \u2265 1, \`maxLength\` must be \u2264 16, and \`minLength\` \u2264 \`maxLength\`, but received: ['minLength': \`${minLength}\`, 'maxLength': \`${maxLength}\`].` ); } const randomLength = minLength === maxLength ? minLength : randomInt(minLength, maxLength); const minValue = 10 ** (randomLength - 1); const maxValue = 10 ** randomLength - 1; let result = randomInt(minValue, maxValue); if (avoidZero && result === 0) { result = minValue; } return result; }; var randomStr = (options) => { if (!chunkSYHPSOUU_cjs.isPlainObject(options)) { options = {}; } const { minLength = 40, maxLength = 40, type = "string", avoidWhiteSpace = true } = options; chunkSYHPSOUU_cjs.assertIsBoolean(avoidWhiteSpace, { message({ currentType, validType }) { return `Parameters \`avoidWhiteSpace\` property of the \`options\` (first-parameter) must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); if (!chunkDVMHRLKP_cjs.isInteger(minLength) || !chunkDVMHRLKP_cjs.isInteger(maxLength)) { throw new TypeError( `Parameters \`minLength\` and \`maxLength\` must be of type \`integer-number\`, but received: ['minLength': \`${chunkSYHPSOUU_cjs.getPreciseType( minLength )}\` - (with value: ${chunkDAPAK2W3_cjs.safeStableStringify(minLength, { keepUndefined: true })}), 'maxLength': \`${chunkSYHPSOUU_cjs.getPreciseType( maxLength )}\` - (with value: ${chunkDAPAK2W3_cjs.safeStableStringify(maxLength, { keepUndefined: true })})].` ); } if (minLength < 1 || maxLength > 5e3 || minLength > maxLength) { throw new RangeError( `Invalid range at parameters \`minLength\` must be \u2265 1, \`maxLength\` must be \u2264 5000, and \`minLength\` \u2264 \`maxLength\`, but received: ['minLength': \`${minLength}\`, 'maxLength': \`${maxLength}\`].` ); } if (type !== "string" && type !== "number") { throw new TypeError( `Parameter \`type\` must be of type \`string\` with value one of "string" | "number", but received: \`${chunkSYHPSOUU_cjs.getPreciseType( type )}\`, with value: ${chunkDAPAK2W3_cjs.safeStableStringify(type, { keepUndefined: true })}.` ); } const length = randomInt(minLength, maxLength); const cleanCharacters = (charSet) => { return avoidWhiteSpace ? charSet.replace(/\s|\n|\t/g, "") : charSet; }; const defaultNumberSet = "0123456789"; const defaultStringSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const baseCharSet = type === "number" ? (!chunkSYHPSOUU_cjs.isNaN(Number(options.replaceGenInt)) ? options.replaceGenInt : void 0) ?? defaultNumberSet : (options.replaceGenStr ? options.replaceGenStr : void 0) ?? defaultStringSet; const characterSet = cleanCharacters(baseCharSet) + (options.addChar || ""); if (!characterSet.length) { const errCharSet = () => { if (type === "number") { if (avoidWhiteSpace) { return `If \`avoidWhiteSpace\` is true, and \`replaceGenInt\` cant be empty-string value, ensure \`replaceGenInt\` has valid characters and non-nan string number.`; } return `Ensure \`replaceGenInt\` has valid characters and not a NaN number string while convert to number.`; } return `Ensure \`replaceGenStr\` has valid characters and non empty string.`; }; throw new Error(`Character set is empty. ${errCharSet()}`); } let result = ""; for (let i = 0; i < length; i++) { result += characterSet.charAt(Math.floor(Math.random() * characterSet.length)); } return result; }; function randomUUID(options = {}) { if (!chunkSYHPSOUU_cjs.isPlainObject(options)) { throw new TypeError( `First parameter (\`options\`) must be a plain object with optional properties \`version\` and \`monotonic\`, but received: \`${chunkSYHPSOUU_cjs.getPreciseType( options )}\` - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(options, { keepUndefined: true })}\`).` ); } const { version = "v4", monotonic = false } = options; if (!chunkSYHPSOUU_cjs.isNonEmptyString(version)) { throw new TypeError( `Parameter \`version\` property of the \`options\` (first parameter) must be a \`string\` of either "v4" or "v7", but received type: \`${chunkSYHPSOUU_cjs.getPreciseType( version )}\` - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(version, { keepUndefined: true })}\`).` ); } if (version !== "v4" && version !== "v7") { throw new RangeError( `Unsupported UUID version. Allowed values are "v4" or "v7". (received: \`${chunkDAPAK2W3_cjs.safeStableStringify( version, { keepUndefined: true } )}\`).` ); } if (!chunkSYHPSOUU_cjs.isBoolean(monotonic)) { throw new TypeError( `Parameter \`monotonic\` property of the \`options\` (first parameter) must be a \`boolean\` when provided, but received type: \`${chunkSYHPSOUU_cjs.getPreciseType( monotonic )}\` - (with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(monotonic, { keepUndefined: true })}\`).` ); } if (monotonic && version !== "v7") { throw new TypeError( `Parameter \`monotonic\` property of the \`options\` (first parameter) is only supported for version "v7". Received: version=${chunkDAPAK2W3_cjs.safeStableStringify( version, { keepUndefined: true } )}.` ); } if (version === "v4") { return generateUUIDv4(); } return generateUUIDv7({ monotonic }); } function hasCryptoGetRandomValues() { return typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function"; } function hasCryptoRandomUUID() { return typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"; } function getRandomBytes(len) { if (hasCryptoGetRandomValues()) { return crypto.getRandomValues(new Uint8Array(len)); } const arr = new Uint8Array(len); for (let i = 0; i < len; i++) { arr[i] = Math.floor(Math.random() * 256); } return arr; } var byteToHex = (() => { const arr = []; for (let i = 0; i < 256; ++i) { arr.push((i + 256).toString(16).substring(1)); } return arr; })(); function generateUUIDv4() { if (hasCryptoRandomUUID()) { return crypto.randomUUID(); } if (hasCryptoGetRandomValues()) { const rnd = crypto.getRandomValues(new Uint8Array(16)); rnd[6] = rnd[6] & 15 | 64; rnd[8] = rnd[8] & 63 | 128; return byteToHex[rnd[0]] + byteToHex[rnd[1]] + byteToHex[rnd[2]] + byteToHex[rnd[3]] + "-" + byteToHex[rnd[4]] + byteToHex[rnd[5]] + "-" + byteToHex[rnd[6]] + byteToHex[rnd[7]] + "-" + byteToHex[rnd[8]] + byteToHex[rnd[9]] + "-" + byteToHex[rnd[10]] + byteToHex[rnd[11]] + byteToHex[rnd[12]] + byteToHex[rnd[13]] + byteToHex[rnd[14]] + byteToHex[rnd[15]]; } return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = Math.random() * 16 | 0; const v = c === "x" ? r : r & 3 | 8; return v.toString(16); }); } var monotonicState = { lastTimestampMs: -1, lastRand: null }; function incrementUint8ArrayBigEndian(arr) { for (let i = arr.length - 1; i >= 0; i--) { if (arr[i] === 255) { arr[i] = 0; continue; } arr[i] = arr[i] + 1 & 255; return false; } return true; } function generateUUIDv7({ monotonic = false } = {}) { const nowMs = Date.now(); const tsHex = BigInt(nowMs).toString(16).padStart(12, "0"); let rand = getRandomBytes(10); if (monotonic) { if (monotonicState.lastTimestampMs === nowMs && monotonicState.lastRand) { const copy = new Uint8Array(monotonicState.lastRand); const overflow = incrementUint8ArrayBigEndian(copy); if (overflow) { throw new RangeError( "Monotonic UUID sequence overflow: too many UUIDs generated within the same millisecond." ); } rand = copy; monotonicState.lastRand = copy; } else { const fresh = getRandomBytes(10); monotonicState.lastRand = new Uint8Array(fresh); monotonicState.lastTimestampMs = nowMs; rand = fresh; } } rand[0] = rand[0] & 15 | 112; rand[2] = rand[2] & 63 | 128; const randHex = Array.from(rand, (b) => byteToHex[b]).join(""); const part1 = tsHex.slice(0, 8); const part2 = tsHex.slice(8, 12); const part3 = randHex.slice(0, 4); const part4 = randHex.slice(4, 8); const part5 = randHex.slice(8, 20); return [part1, part2, part3, part4, part5].join("-"); } exports.getRandomItem = getRandomItem; exports.randomInt = randomInt; exports.randomIntByLength = randomIntByLength; exports.randomStr = randomStr; exports.randomUUID = randomUUID;