UNPKG

@catbee/utils

Version:

A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.

369 lines (366 loc) 14.9 kB
/* * The MIT License * * Copyright (c) 2026 Catbee Technologies. https://catbee.in/license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /** * Splits an array into chunks of the specified size. * * @template T The type of array elements. * @param {T[]} array - The array to split into chunks. * @param {number} size - The number of elements per chunk. * @returns {T[][]} A new array containing chunked arrays. * @throws {TypeError} If array is not an array. * @throws {Error} If chunk size is not a positive integer. */ declare function chunk<T>(array: readonly T[], size: number): T[][]; /** * Removes duplicate values from an array. * Optionally enforces uniqueness by a key function. * * @template T The type of array elements. * @param {T[]} array - The input array. * @param {(item: T) => unknown} [keyFn] - Optional function to determine uniqueness by key. * @returns {T[]} A new array with unique values. */ declare function unique<T>(array: readonly T[], keyFn?: (item: T) => unknown): T[]; /** * Deeply flattens a nested array to a single-level array (iterative, stack-based). * * @template T The leaf type of array elements. * @param {readonly unknown[]} array - The (possibly deeply nested) input array. * @returns {T[]} A deeply flattened array. */ declare function flattenDeep<T>(array: readonly unknown[]): T[]; /** * Returns a random element from an array, or undefined if empty. Uses crypto-secure randomness * * @template T The type of array elements. * @param {T[]} array - The input array. * @returns {T | undefined} A randomly selected item, or undefined if array is empty or not an array. * * @example * ```ts * securePick(['a','b','c']); // -> 'b' * ``` */ declare function random<T>(array: readonly T[]): T | undefined; type StrNumSym = string | number | symbol; /** * Groups items in an array by a nested key or key function. * * @template T The type of array elements. * @overload * @param {T[]} array - The array to group. * @param {keyof T} key - Property key to group by. * @returns {Record<string, readonly T[]>} * @overload * @param {T[]} array - The array to group. * @param {(item: T) => StrNumSym} keyFn - Function to generate group key from item. * @returns {Record<K, readonly T[]>} * @param {T[]} array - The array to group. * @param {keyof T | ((item: T) => StrNumSym)} keyOrFn - Nested property key or key selector. * @returns {Record<StrNumSym, readonly T[]>} Grouped result object. */ declare function groupBy<T>(array: T[], key: keyof T): Record<string, readonly T[]>; declare function groupBy<T, K extends StrNumSym>(array: T[], keyFn: (item: T) => K): Record<K, readonly T[]>; /** * Shuffles an array using the Fisher-Yates algorithm. Uses crypto-secure randomness. * * @template T The type of array elements. * @param {T[]} array - The input array. * @returns {T[]} A new shuffled array. * @throws {TypeError} If array is not an array. */ declare function shuffle<T>(array: readonly T[]): T[]; /** * Returns an array of property values from an array of objects. Returns undefined for missing properties. * * @template T The type of array elements. * @template K The object property to pluck. * @param {T[]} array - The input array. * @param {K} key - The property name to pluck. * @returns {T[K][]} Array of property values. */ declare function pluck<T, K extends keyof T>(array: readonly T[], key: K): T[K][]; /** * Returns values in array A that are not in array B. * * @template T The type of array elements. * @param {T[]} a - First array. * @param {T[]} b - Second array. * @returns {T[]} Elements in A that are not in B. */ declare function difference<T>(a: readonly T[], b: readonly T[]): T[]; /** * Returns common values between arrays A and B. * * @template T The type of array elements. * @param {T[]} a - First array. * @param {T[]} b - Second array. * @returns {T[]} Elements that exist in both arrays. */ declare function intersect<T>(a: readonly T[], b: readonly T[]): T[]; /** * Sorts an array of objects by a nested key using Merge Sort (O(n log n)). * Missing/undefined keys are sorted to the "end" (asc) or "start" (desc"). * Optionally accepts a custom compare function or collator. * * @template T The type of array elements (objects). * @param {T[]} array - Array of objects to sort. * @param {string | ((item: T) => any)} key - Dot-notated key (e.g., "profile.age") or function. * @param {"asc" | "desc"} [direction="asc"] - Sort direction: 'asc' or 'desc'. * @param {(a: T, b: T) => number} [compareFn] - Optional custom compare function. * @returns {T[]} A new sorted array. * @throws {TypeError} If array is not an array. */ declare function mergeSort<T>(array: readonly T[], key: string | ((item: T) => unknown), direction?: 'asc' | 'desc', compareFn?: (a: T, b: T) => number): T[]; /** * Combines multiple arrays into a single array of grouped elements. * Output length equals the length of the shortest input array. * * This implementation ensures type safety and avoids holes in output. * * @example * ```ts * zip([1, 2], ['a', 'b']) => [[1, 'a'], [2, 'b']] * ``` * @param {...Array<T>[]} arrays - Two or more arrays to zip together. * @returns {Array<T[]>} Array of grouped elements. */ declare function zip<T>(...arrays: ReadonlyArray<T>[]): T[][]; /** * Splits an array into two arrays based on a predicate function. * Supports type-guard narrowing via overload. * * @template T The type of array elements. * @overload * @param {readonly T[]} array - The input array. * @param {(item: T, index: number, array: readonly T[]) => item is U} predicate - Type guard predicate. * @returns {[U[], Exclude<T, U>[]]} A tuple of two arrays: [matched, unmatched]. * @overload * @param {readonly T[]} array - The input array. * @param {(item: T, index: number, array: readonly T[]) => boolean} predicate - Boolean predicate. * @returns {[T[], T[]]} A tuple of two arrays: [matched, unmatched]. */ declare function partition<T, U extends T>(array: readonly T[], predicate: (item: T, index: number, array: readonly T[]) => item is U): [U[], Exclude<T, U>[]]; declare function partition<T>(array: readonly T[], predicate: (item: T, index: number, array: readonly T[]) => boolean): [T[], T[]]; /** * Generates an array of numbers within a specified range. * * @param {number} start - Start of range (inclusive). * @param {number} end - End of range (exclusive). * @param {number} [step=1] - Step between numbers. * @returns {number[]} Array of numbers in range. */ declare function range(start: number, end: number, step?: number): number[]; /** * Returns the first `n` elements from an array. * * @template T The type of array elements. * @param {T[]} array - The input array. * @param {number} [n=1] - Number of elements to take. * @returns {T[]} New array with first n elements. */ declare function take<T>(array: readonly T[], n?: number): T[]; /** * Takes elements from an array while predicate returns true. * * @template T The type of array elements. * @param {readonly T[]} array - Input array. * @param {(item: T, index: number) => boolean} predicate - Condition function. * @returns {T[]} New array with taken elements. * * @example * ```ts * takeWhile([1,2,3,4], (n) => n < 3); // -> [1,2] * ``` */ declare function takeWhile<T>(array: readonly T[], predicate: (item: T, index: number) => boolean): T[]; /** * Removes all falsy values from an array. * `false`, `null`, `0`, `""`, `undefined`, and `NaN` are falsy. * * @template T The type of array elements. * @param {T[]} array - The input array. * @returns {NonNullable<T>[]} New array with falsy values removed. */ declare function compact<T>(array: readonly T[]): NonNullable<T>[]; /** * Counts array elements by a key function. * * @template T The type of array elements. * @param {T[]} array - The input array. * @param {(item: T) => StrNumSym} keyFn - Function to generate count key. * @returns {Record<string, number>} Object with counts by key. */ declare function countBy<T>(array: readonly T[], keyFn: (item: T) => StrNumSym): Record<string, number>; /** * Toggles an item in array (adds if not present, removes if present). * * @template T * @param {readonly T[]} array * @param {T} item * @returns {T[]} New array with item toggled. * * @example * ```ts * toggle([1,2,3], 2); // -> [1,3] * toggle([1,3], 2); // -> [1,3,2] * ``` */ declare function toggle<T>(array: readonly T[], item: T): T[]; /** * Returns a cryptographically secure random index for an array. * Used internally for secure pick/shuffle operations. * * @param {number} max Upper bound (exclusive). * @returns {number} A secure random integer in range `[0, max)`. * @throws {RangeError} If `max` is not a positive number. * * @example * ```ts * secureIndex(10); // -> 3 (unpredictable) * ``` */ declare function secureIndex(max: number): number; /** * Returns a secure random element from an array using Node crypto. * * @template T * @param {readonly T[]} array * @returns {T | undefined} */ declare const secureRandom: <T>(array: readonly T[]) => T | undefined; /** * Returns the last element in the array that satisfies the provided testing function. * * @template T * @param {readonly T[]} array - The input array. * @param {(item: T, index: number, array: readonly T[]) => boolean} predicate - Function to test each element. * @returns {T | undefined} The found element, or undefined if not found. */ declare function findLast<T>(array: readonly T[], predicate: (item: T, index: number, array: readonly T[]) => boolean): T | undefined; /** * Returns the index of the last element in the array that satisfies the provided testing function. * * @template T * @param {readonly T[]} array - The input array. * @param {(item: T, index: number, array: readonly T[]) => boolean} predicate - Function to test each element. * @returns {number} The index, or -1 if not found. */ declare function findLastIndex<T>(array: readonly T[], predicate: (item: T, index: number, array: readonly T[]) => boolean): number; /** * Splits an array into chunks based on a predicate function. * Each chunk starts when predicate returns true. * * @template T * @param {readonly T[]} array - The input array. * @param {(item: T, index: number, array: readonly T[]) => boolean} predicate - Function to determine chunk boundaries. * @returns {T[][]} Array of chunked arrays. */ declare function chunkBy<T>(array: readonly T[], predicate: (item: T, index: number, array: readonly T[]) => boolean): T[][]; /** * Removes all occurrences of a value from an array. * * @template T * @param {readonly T[]} array - The input array. * @param {T} value - Value to remove. * @returns {T[]} New array with value removed. */ declare function remove<T>(array: readonly T[], value: T): T[]; /** * Checks if an array is sorted in ascending or descending order. * * @template T * @param {readonly T[]} array - The input array. * @param {'asc' | 'desc'} [direction='asc'] - Sort direction. * @param {(a: T, b: T) => number} [compareFn] - Optional compare function. * @returns {boolean} True if sorted, false otherwise. */ declare function isSorted<T>(array: readonly T[], direction?: 'asc' | 'desc', compareFn?: (a: T, b: T) => number): boolean; /** * Returns the first element of an array, or undefined if empty. * * @template T * @param {readonly T[]} array * @returns {T | undefined} */ declare function headOfArr<T>(array: readonly T[]): T | undefined; /** * Returns the last element of an array, or undefined if empty. * * @template T * @param {readonly T[]} array * @returns {T | undefined} */ declare function lastOfArr<T>(array: readonly T[]): T | undefined; /** * Drops the first n elements from an array. * * @template T * @param {readonly T[]} array - The source array. * @param {number} n - Number of elements to drop. * @returns {T[]} Array with first n elements removed. * * @example * drop([1, 2, 3, 4, 5], 2); // [3, 4, 5] */ declare function drop<T>(array: readonly T[], n: number): T[]; /** * Drops elements from the start of an array while predicate returns true. * * @template T * @param {readonly T[]} array - The source array. * @param {(item: T, index: number) => boolean} predicate - Condition function. * @returns {T[]} Array with elements dropped. * * @example * dropWhile([1, 2, 3, 4, 1], x => x < 3); // [3, 4, 1] */ declare function dropWhile<T>(array: readonly T[], predicate: (item: T, index: number) => boolean): T[]; /** * Finds the element with the maximum value for a given key or function. * * @template T * @param {readonly T[]} array - The source array. * @param {keyof T | ((item: T) => number)} keyOrFn - Property key or function. * @returns {T | undefined} Element with maximum value. * * @example * maxBy([{a: 1}, {a: 5}, {a: 3}], 'a'); // {a: 5} * maxBy([{a: 1}, {a: 5}, {a: 3}], x => x.a); // {a: 5} */ declare function maxBy<T>(array: readonly T[], keyOrFn: keyof T | ((item: T) => number)): T | undefined; /** * Finds the element with the minimum value for a given key or function. * * @template T * @param {readonly T[]} array - The source array. * @param {keyof T | ((item: T) => number)} keyOrFn - Property key or function. * @returns {T | undefined} Element with minimum value. * * @example * minBy([{a: 1}, {a: 5}, {a: 3}], 'a'); // {a: 1} * minBy([{a: 1}, {a: 5}, {a: 3}], x => x.a); // {a: 1} */ declare function minBy<T>(array: readonly T[], keyOrFn: keyof T | ((item: T) => number)): T | undefined; export { chunk, chunkBy, compact, countBy, difference, drop, dropWhile, findLast, findLastIndex, flattenDeep, groupBy, headOfArr, intersect, isSorted, lastOfArr, maxBy, mergeSort, minBy, partition, pluck, random, range, remove, secureIndex, secureRandom, shuffle, take, takeWhile, toggle, unique, zip };