@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.
197 lines (194 loc) • 7.99 kB
TypeScript
/*
* 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.
*/
/**
* Safely checks if a value is an object (not null, not array).
*
* @param {unknown} value - Value to check.
* @returns {boolean} True if value is a non-null, non-array object.
*/
declare function isObject(value: unknown): value is Record<string, any>;
/**
* Checks whether the object has no own enumerable properties.
*
* @param {Record<any, any>} obj - The object to check.
* @returns {boolean} True if the object is empty, false otherwise.
*/
declare function isObjEmpty(obj: Record<any, any>): boolean;
/**
* Returns a new object with only the specified keys picked.
*
* @template T
* @template K
* @param {T} obj - The source object.
* @param {K[]} keys - Keys to pick from the object.
* @returns {Pick<T, K>} New object with picked keys.
*/
declare function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>;
/**
* Returns a new object with the specified keys omitted.
*
* @template T
* @template K
* @param {T} obj - The source object.
* @param {K[]} keys - Keys to omit from the object.
* @returns {Omit<T, K>} New object without omitted keys.
*/
declare function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
/**
* Deeply merges multiple sources into the target object (mutates and returns the target, not pure).
* Uses the project’s existing `deepClone` to handle all cloning and circular references.
*
* @template T
* @param {T} target - The object to merge into (will be mutated)
* @param {...any[]} sources - The objects to merge from
* @returns {T} The merged object (same reference as target)
*/
declare function deepObjMerge<T extends object>(target: T, ...sources: any[]): T;
/**
* Checks if a value is a plain object (i.e., not an array, null, or a built-in object).
*
* @param value - The value to check.
* @returns True if the value is a plain object, false otherwise.
*/
declare function isPlainObject(value: any): value is Record<string, any>;
/**
* Flattens a nested object using dot notation for keys (e.g., `{a: {b: 1}}` -> `{ "a.b": 1 }`).
*
* @template T
* @param {T} obj - The object to flatten.
* @param {string} [prefix=""] - Optional prefix for nested keys (used internally).
* @returns {Record<string, any>} A new object with flattened keys.
*/
declare function flattenObject<T extends Record<string, any>>(obj: T, prefix?: string): Record<string, any>;
/**
* Safely gets the value of a deeply nested key in an object using dot/bracket notation path.
*
* @template T
* @param {T} obj - The object to extract from.
* @param {string} path - String path using dot and/or bracket notation (e.g., 'user.friends[0].name').
* @returns {any} The value at the given path, or undefined if not found.
*/
declare function getValueByPath<T extends object>(obj: T, path: string): any;
/**
* Sets a value at a deeply nested key in an object using dot/bracket notation path.
* Secured against prototype pollution.
*
* @template T
* @param {T} obj - The object to modify.
* @param {string} path - Dot/bracket notation path (e.g., "user.friends[0].name").
* @param {any} value - Value to assign.
* @returns {T} The new object with the value set (original object is not mutated).
*/
declare function setValueByPath<T extends object>(obj: T, path: string, value: any): T;
/**
* Performs a deep equality check between two objects.
*
* @param {any} a - First value to compare.
* @param {any} b - Second value to compare.
* @returns {boolean} True if values are deeply equal.
*/
declare function isEqual(a: any, b: any): boolean;
/**
* Filters object properties based on a predicate function.
*
* @template T
* @param {T} obj - The source object.
* @param {(value: any, key: string, obj: T) => boolean} predicate - Filter function.
* @returns {Partial<T>} New object with filtered properties.
*/
declare function filterObject<T extends object>(obj: T, predicate: (value: any, key: string, obj: T) => boolean): Partial<T>;
/**
* Maps object values to new values using a mapping function.
*
* @template T
* @template U
* @param {T} obj - The source object.
* @param {(value: any, key: string, obj: T) => U} mapFn - Mapping function.
* @returns {Record<keyof T, U>} New object with mapped values.
*/
declare function mapObject<T extends object, U>(obj: T, mapFn: (value: any, key: string, obj: T) => U): Record<keyof T, U>;
/**
* Deeply clones any value.
* Preserves functions and symbols by reference.
* Handles circular references using `WeakMap`.
*
* @template T The type of the value being cloned.
* @param value The value to deeply clone.
* @returns A fully deep-cloned copy of the input.
*/
declare function deepClone<T>(value: T): T;
/**
* Recursively freezes an object and all its properties.
* Makes an object immutable.
*
* @template T
* @param {T} obj - The object to freeze.
* @returns {Readonly<T>} The frozen object.
*/
declare function deepFreeze<T extends object>(obj: T): Readonly<T>;
/**
* Gets all paths in an object using dot notation.
*
* @param {Record<string, any>} obj - Object to analyze.
* @param {string} [parentPath=""] - Internal param for recursion.
* @returns {string[]} Array of all paths in dot notation.
*/
declare function getAllPaths(obj: Record<string, any>, parentPath?: string): string[];
/**
* Inverts an object's keys and values.
*
* @template T
* @param {T} obj - The object to invert.
* @returns {Record<string, string>} Inverted object.
*
* @example
* invert({ a: 'x', b: 'y' }); // { x: 'a', y: 'b' }
*/
declare function invert<T extends Record<string, any>>(obj: T): Record<string, string>;
/**
* Inverts an object using a function to generate keys from values.
*
* @template T
* @param {T} obj - The object to invert.
* @param {(value: any) => string} keyFn - Function to generate new keys.
* @returns {Record<string, string[]>} Inverted object with arrays of keys.
*
* @example
* invertBy({ a: 1, b: 2, c: 1 }, v => String(v)); // { '1': ['a', 'c'], '2': ['b'] }
*/
declare function invertBy<T extends Record<string, any>>(obj: T, keyFn: (value: any) => string): Record<string, string[]>;
/**
* Transforms object values using a mapping function.
*
* @template T
* @template U
* @param {T} obj - The source object.
* @param {(value: any, key: string) => U} fn - Transformation function.
* @returns {Record<string, U>} Object with transformed values.
*
* @example
* transform({ a: 1, b: 2 }, v => v * 2); // { a: 2, b: 4 }
*/
declare function transform<T extends Record<string, any>, U>(obj: T, fn: (value: any, key: string) => U): Record<string, U>;
export { deepClone, deepFreeze, deepObjMerge, filterObject, flattenObject, getAllPaths, getValueByPath, invert, invertBy, isEqual, isObjEmpty, isObject, isPlainObject, mapObject, omit, pick, setValueByPath, transform };