UNPKG

@rzl-zone/utils-js

Version:

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

1,153 lines 186 kB
import{FormatOptions}from 'date-fns';import{Locale}from 'date-fns/locale';type If<Condition,IfTrue=true,IfFalse=false>=Condition extends true ? IfTrue:IfFalse;type Not<T extends boolean>=T extends true ? false:true;type Extends<T,Base>=[T] extends [Base] ? true:false;type NotExtends<T,Base>=Not<Extends<T,Base>>;type IfExtends<T,Base,IfTrue=true,IfFalse=false>=If<Extends<T,Base>,IfTrue,IfFalse>;type IfNotExtends<T,Base,IfTrue=true,IfFalse=false>=If<NotExtends<T,Base>,IfTrue,IfFalse>;type IsAny<T>=0 extends 1 & T ? true:false;type PrettifyOptions={recursive:boolean;};type Prettify<T,Options extends PrettifyOptions={recursive:false;}>=T extends infer R ?{[K in keyof R]:If<Options["recursive"],Prettify<R[K],Options>,R[K]>;}:never;type OmitStrict<T,K extends keyof T,WithPrettify extends boolean=true,WithPrettifyRecursive extends boolean=true>=WithPrettify extends true ? Prettify<Omit<T,K>,{recursive:WithPrettifyRecursive;}>:WithPrettify extends false ? Omit<T,K>:never;type AnyFunction=(...args:any[])=>any;type TypedArray=Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;type WebApiObjects=URL | URLSearchParams | FormData | Headers | Response | Request | ReadableStream<any>| WritableStream<any>| TransformStream<any,any>| MessageChannel | MessagePort | MessageEvent | Event | CustomEvent | HTMLElement | Node | Document | Window | AbortController | AbortSignal | TextEncoder | TextDecoder | CryptoKey | File | FileList | ImageBitmap | CanvasRenderingContext2D | WebSocket;type IntlObjects=Intl.Collator | Intl.DateTimeFormat | Intl.NumberFormat | Intl.RelativeTimeFormat | Intl.PluralRules | Intl.ListFormat | Intl.Locale;type NodeBuiltins=Buffer;type NonPlainObject=AnyFunction | Array<any>| Date | RegExp | Map<any,any>| Set<any>| WeakMap<any,any>| WeakSet<any>| Error | Promise<any>| ArrayBuffer | DataView | TypedArray | WebApiObjects | IntlObjects | NodeBuiltins | symbol |{[Symbol.toStringTag]:"Proxy";}| typeof Reflect;type Enumerate<N extends number,Acc extends number[]=[]>=Acc["length"] extends N ? Acc[number]:Enumerate<N,[...Acc,Acc["length"]]>;type RangeNumberTo999<From extends number,To extends number>=From extends To ? From:Exclude<Enumerate<To>,Enumerate<From>>extends never ? never:Exclude<Enumerate<To>,Enumerate<From>>| To; /** ------------------------------------------------------- * * ***Asserts that a value is of type `string`.*** * ------------------------------------------------------- * * Throws a `TypeError` if the value is not a string. * * @param {unknown} value - The value to check. * @param {string | ((actualType: string) => string)} [message] * Optional custom error message. If a function is provided, * it receives the actual type (e.g. "number") and should return a string message. * @returns {asserts value is string} Ensures `value` is `string` after this call. * * @throws {TypeError} If the value is not a string. * * @example * assertIsString("hello"); // ✅ ok * * @example * assertIsString(42); // ❌ throws TypeError: Expected value to be 'string', but got 'number' * * @example * assertIsString(42, "Must be a string!"); // ❌ throws: Must be a string! * * @example * assertIsString(42, (type) => `Expected string but got ${type}`); // ❌ throws: Expected string but got number */ declare const assertIsString:(value:unknown,message?:string |((typeValue:string)=>string))=>asserts value is string; /** --------------------------------------------- * * ***Converts all values in an array from numbers or other types to strings.*** * * ***The function can also remove invalid values (null, undefined) based on the options provided.*** * --------------------------------- * * * 🚫 Note: This function does NOT support recursive or nested arrays. * It only processes a flat array of values. * * * Use `toStringDeep` if you want to recursive. * --------------------------------------------- * * @param {Array<string | number | null | undefined>} [array] - The array to be transformed. * @param {Object} [options] - The options object that controls the transformation behavior. * @param {boolean} [options.removeInvalidValue=true] - If true, removes invalid values (null, undefined) from the result. Default is true. * @returns {Array<string | null | undefined>} - A new array with string representations of the values or an array with invalid values removed if specified. * * @example * toStringArrayUnRecursive([1, 2, '3']) * // => ['1', '2', '3'] * * @example * toStringArrayUnRecursive([1, null, undefined, 'abc'], { removeInvalidValue: true }) * // => ['1', 'abc'] * * @example * toStringArrayUnRecursive([1, null, undefined, 'abc'], { removeInvalidValue: false }) * // => ['1', null, undefined, 'abc'] * * @example * toStringArrayUnRecursive(undefined) * // => undefined */ declare function toStringArrayUnRecursive(array?:undefined | null,options?:{ /** If true, removes invalid values (null, undefined) from the result. Default is true. * @default true */ removeInvalidValue:boolean;}):undefined;declare function toStringArrayUnRecursive(array?:Array<never>,options?:{ /** If true, removes invalid values (null, undefined) from the result. Default is true. * @default true */ removeInvalidValue:boolean;}):Array<never>;declare function toStringArrayUnRecursive(array?:Array<undefined | null>| Array<null | undefined>,options?:{ /** If true, removes invalid values (null, undefined) from the result. Default is true. * @default true */ removeInvalidValue:boolean;}):Array<undefined>;declare function toStringArrayUnRecursive<T>(array?:Array<T>,options?:{ /** If true, removes invalid values (null, undefined) from the result. Default is true. * @default true */ removeInvalidValue:true;}):Array<string>| undefined;declare function toStringArrayUnRecursive<T>(array?:Array<T>,options?:{ /** If true, removes invalid values (null, undefined) from the result. Default is true. * @default true */ removeInvalidValue:false;}):Array<string | null | undefined>| undefined; /** --------------------------------- * * ***Converts an array of string values (or values that can be cast to string) to an array of numbers.*** * * ***Optionally removes invalid values (non-numeric values) based on the provided options.*** * --------------------------------- * * * 🚫 Note: This function does NOT support recursive or nested arrays. * It only processes a flat array of values. * * * Use `toNumbersDeep` if you want to recursive. * --------------------------------- * * @param {Array<string | null | undefined>} [array] - The array of string values (or values convertible to strings) to be transformed into numbers. * @param {Object} [options] - Options that affect the conversion behavior. * @param {boolean} [options.removeInvalidValueNumber=true] - If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * @returns {Array<number | undefined>} - An array of numbers converted from the string values, or an array with invalid values removed if specified. */ declare function toNumberArrayUnRecursive(array?:undefined | null,options?:{ /** If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * * @default true */ removeInvalidValueNumber?:boolean;}):undefined;declare function toNumberArrayUnRecursive(array?:Array<never>,options?:{ /** If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * * @default true */ removeInvalidValueNumber?:boolean;}):Array<never>;declare function toNumberArrayUnRecursive(array?:Array<undefined | null>| Array<null | undefined>,options?:{ /** If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * * @default true */ removeInvalidValueNumber?:boolean;}):Array<undefined>;declare function toNumberArrayUnRecursive<T>(array?:Array<T>,options?:{ /** If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * * @default true */ removeInvalidValueNumber?:true;}):Array<number>| undefined;declare function toNumberArrayUnRecursive<T>(array?:Array<T>,options?:{ /** If true, removes invalid number values (e.g., NaN, undefined) from the result. Default is true. * * @default true */ removeInvalidValueNumber:false;}):Array<number | undefined>| undefined;type ResUnFTN<Force extends false | "stringOrNumber" | "primitives" | "all"=false>=Force extends "all" ? Array<unknown[] | Record<string,unknown>| string>:Force extends "stringOrNumber" ? Array<string | boolean | bigint | symbol | null | undefined | Record<string,unknown>| AnyFunction | unknown[] | Date | RegExp | Map<unknown,unknown>| Set<unknown>| Promise<unknown>>:Force extends "primitives" ? Array<string | symbol | Record<string,unknown>| AnyFunction | unknown[] | Date | RegExp | Map<unknown,unknown>| Set<unknown>| Promise<unknown>>:Force extends false ? Array<string | number | bigint | boolean | symbol | RegExp | Record<string,unknown>| AnyFunction | Date | Map<unknown,unknown>| Set<unknown>| Promise<unknown>| unknown[] | null | undefined>:unknown[];type ResFTN<Force extends false | "stringOrNumber" | "primitives" | "all"=false>=Force extends "all" ? Array<string | Record<string,unknown>>:Force extends "stringOrNumber" ? Array<string | boolean | bigint | symbol | null | undefined | Record<string,unknown>| AnyFunction | Date | RegExp | Promise<unknown>>:Force extends "primitives" ? Array<string | symbol | RegExp | Record<string,unknown>| AnyFunction | Date | Promise<unknown>>:Force extends false ? Array<string | number | bigint | boolean | symbol | RegExp | Record<string,unknown>| AnyFunction | Date | Promise<unknown>| null | undefined>:unknown[];type DedupeResult<Force extends false | "stringOrNumber" | "primitives" | "all"=false,FTN extends boolean=false>=FTN extends false ? ResUnFTN<Force>:ResFTN<Force>; /** ---------------------------------------------------------- * * ***Removes `null` and `undefined` values from an array, including nested arrays.*** * ---------------------------------------------------------- * * - ✅ Returns `undefined` if the input is explicitly `undefined` or `null`. * - ✅ Returns `[]` if input is empty or all elements are removed after filtering. * - ✅ Recursively filters nested arrays while preserving structure. * - ✅ Ensures proper type inference for safer downstream operations. * * @template T - The type of elements in the array. * @param {T[]} [input] - The array to be filtered. * @returns {T[] | undefined} A new array with `null` and `undefined` values removed, * or `undefined` if the input is explicitly `undefined` or `null`. * * @example * filterNullArray([1, null, 2, undefined, 3]); * // => [1, 2, 3] * * @example * filterNullArray([null, undefined]); * // => [] * * @example * filterNullArray(undefined); * // => undefined * @example * filterNullArray(null); * // => undefined * * @example * filterNullArray([]); * // => [] * * @example * filterNullArray([1, [null, 2, [undefined, 3]]]); * // => [1, [2, [3]]] */ declare const filterNullArray:<T>(input?:T[] | null)=>T[] | undefined; /** ---------------------------------------------------------- * * ***Deduplicates values in an array (with optional flattening and deep stringification).*** * ---------------------------------------------------------- * * Supports various modes for converting values to strings before deduplication: * - `"stringOrNumber"`: Converts strings and numbers to strings. * - `"primitives"`: Converts all primitives (string, number, boolean, bigint, null, undefined, NaN) to strings. * - `"all"`: Converts all values (primitives, objects, Maps, Sets, Symbols, RegExp, Dates, Errors, Promises, functions) * to strings, including nested object properties. * - `false` (default): No conversion applied. * * Options: * - `forceToString`: Enables string conversion for comparison, default is `false`. * - `flatten`: If true, deeply flattens arrays, Maps, and Sets before deduplication, default is `false`. * * @template FTS - `forceToString` mode. * @template FTN - `flatten` mode. * * @param {unknown[]} inputArray - The array to deduplicate. Can be deeply nested and contain any mix of types. * @param {{ forceToString?: false | "stringOrNumber" | "primitives" | "all" }} [options] - Options to control string conversion. * @returns {DedupeResult<FTS, FTN>} Deduplicated array with optional transformations. * * @throws {TypeError} If the input is not an array, or options is not an object, or if `forceToString` is invalid. * * @example * dedupeArray(["apple", "banana", "apple"]); * // => ["apple", "banana"] * * @example * dedupeArray([[1, 2], [1, 2]], { flatten: true }); * // => [1, 2] * * @example * dedupeArray([new Set([1, 2]), new Set([2, 3])], { flatten: true }); * // => [1, 2, 3] * * @example * dedupeArray([1, "1", 2, "2"], { forceToString: "stringOrNumber" }); * // => ["1", "2"] * * @example * dedupeArray([true, "true", false, undefined], { forceToString: "primitives" }); * // => ["true", "false", "undefined"] * * @example * dedupeArray([1, "1", { a: 1 }], { forceToString: "all" }); * // => ["1", { a: "1" }] * * @example * dedupeArray([1, 1, [2, 2, [3, 3]]]); * // => [1, [2, [3]]] * * @example * dedupeArray([null, undefined, null]); * // => [null, undefined] * * @example * dedupeArray([[], [[]], [[[]]], [[]], [[[]]]]); * // => [[], [[]], [[[]]]] * * @example * const fn = () => 1; * dedupeArray([fn, fn, () => 1]); * // => [fn, () => 1] cause: ref () => 1 and fn is different but ref const `fn` and `fn` is same ref. * * @example * dedupeArray([Symbol("x"), Symbol("x")]); * // => [Symbol("x")] (symbols are same by identity, so dedupe * * @example * dedupeArray([NaN, NaN, 1, "1"]); * // => [NaN, 1, "1"] * * @example * dedupeArray([NaN, NaN, 1, "1"], { forceToString: "primitives" }); * // => ["NaN", "1"] * * @example * dedupeArray([new Date("2025-01-01"), new Date("2025-01-01")]); * // => [Date("2025-01-01")] (same time, deduped) * * @example * dedupeArray([new Date("2025-01-01"), new Date("2025-01-01")], { forceToString: "all" }); * // => ["2025-01-01T00:00:00.000Z"] * * @example * dedupeArray([/abc/, /abc/], { forceToString: "all" }); * // => ["/abc/"] * * @example * dedupeArray([new Map(), new Set(), new Error("err")], { forceToString: "all" }); * // => ["[object Map]", "[object Set]", "Error: err"] * * @example * dedupeArray([Promise.resolve(1), Promise.resolve(1)], { forceToString: "all" }); * // => ["[object Promise]"] * * @example * dedupeArray([{ a: 1 }, { a: 1 }, { a: 2 }], { forceToString: "primitives" }); * // => [{ a: "1" }, { a: "2" }] * * @example * dedupeArray([{ a: { b: 1 } }, { a: { b: 1 } }], { forceToString: "all" }); * // => [{ a: { b: "1" } }] * * @example * dedupeArray("not an array"); * // Throws TypeError * * @example * dedupeArray([1, 2, 3], { forceToString: "invalid" }); * // Throws TypeError */ declare const dedupeArray:<FTS extends false | "stringOrNumber" | "primitives" | "all"=false,FTN extends boolean=false>(inputArray:unknown[],options?:{ /** Enables string conversion for comparison, default is `false`. * * @default false */ forceToString?:FTS; /** If true, deeply flattens arrays, Maps, and Sets before deduplication, default is `false`. * * @default false */ flatten?:FTN;})=>DedupeResult<FTS,FTN>; /** --------------------------------- * * ***Converts a given value into a boolean (strict).*** * --------------------------------- * * This is stricter than normal JS coercion: * - `null` and `undefined` return `false`. * - Empty strings return `false`, non-empty strings return `true`. * - Numbers: `0` is `false`, others `true`. * - Booleans returned as-is. * - Arrays: `[]` is `false`, non-empty is `true`. * - Objects: `{}` is `false`, object with keys is `true`. * * @param {unknown} [value] - The value to be converted. * @returns {boolean} `true` if the value is considered non-empty, otherwise `false`. * * @example * toBooleanContent(null); // false * toBooleanContent(""); // false * toBooleanContent(" "); // false * toBooleanContent(" asd "); // true * toBooleanContent("abc"); // true * toBooleanContent(0); // false * toBooleanContent(42); // true * toBooleanContent([]); // false * toBooleanContent([1]); // true * toBooleanContent({}); // false * toBooleanContent({ a: 1 }); // true */ declare const toBooleanContent:(value?:unknown)=>boolean; /** ------------------------------------------------- * * ***Recursively checks if value is "non-empty".*** * ------------------------------------------------- * * This function does a deep inspection to determine if the input * contains any meaningful / non-empty value. It is stricter than * JavaScript's normal truthy checks because it looks *inside* * nested arrays & objects. * * Rules: * - `null` and `undefined` return `false` * - Empty strings `""` return `false` * - `0` returns `false` * - Empty arrays `[]` or empty objects `{}` return `false` * - Checks deeply nested arrays/objects — if any value inside is "non-empty", returns `true` * * @param {unknown} [value] - The value to check. * @returns {boolean} `true` if the value or anything nested inside is non-empty, otherwise `false`. * * @example * toBooleanContentDeep(null); // false * toBooleanContentDeep(""); // false * toBooleanContentDeep(0); // false * toBooleanContentDeep([]); // false * toBooleanContentDeep({}); // false * toBooleanContentDeep([[], {}]); // false * * toBooleanContentDeep("abc"); // true * toBooleanContentDeep(42); // true * toBooleanContentDeep([0, "", null]); // false * toBooleanContentDeep([0, "", 5]); // true * toBooleanContentDeep({ a: 0 }); // false * toBooleanContentDeep({ a: 1 }); // true * toBooleanContentDeep({ a: { b: [] }}); // false * toBooleanContentDeep({ a: { b: "x" }}); // true */ declare const toBooleanContentDeep:(value?:unknown)=>boolean; /** --------------------------------- * * ***Converts a value into a strict boolean.*** * --------------------------------- * * This function checks if the input is a valid representation of `true` * (e.g., `"true"`, `"on"`, `"yes"`, `"1"`, `1`, `true`, `"indeterminate"`). * Any other value, including `undefined` and `null`, will return `false`. * * Supports optional `caseInsensitive` and `trimString` to customize string normalization. * * @param {unknown} [value] - The value to convert. * @param {Object} [options] - Options for conversion behavior. * @param {boolean} [options.caseInsensitive=false] - Whether string comparison ignores case. Default: `false`. * @param {boolean} [options.trimString=true] - Whether to trim whitespace before comparison. Default: `true`. * @returns {boolean} `true` if the value matches a truthy representation, otherwise `false`. * * @example * toBooleanExplicit(true) // true * toBooleanExplicit("on") // true * toBooleanExplicit("Yes") // false * toBooleanExplicit(" YES ", { trimString: false }) // false * toBooleanExplicit(" YES ", { trimString: true, caseInsensitive: true }) // true * toBooleanExplicit(" YES ", { trimString: true, caseInsensitive: false }) // false * toBooleanExplicit("yes", { caseInsensitive: false }) // true * toBooleanExplicit("1") // true * toBooleanExplicit(1) // true * toBooleanExplicit(0) // false * toBooleanExplicit("off") // false */ declare const toBooleanExplicit:(value?:unknown,options?:{ /** Whether string comparison ignores case. Default: `false`. * * @default false */ caseInsensitive?:boolean; /** Whether to trim whitespace before comparison. Default: `true`. * * @default true */ trimString?:boolean;})=>boolean; /** --------------------------------- * * ***Converts a given value into a boolean (loose).*** * --------------------------------- * * This follows JavaScript's typical truthy/falsy rules with some tweaks: * - `null` and `undefined` return `false`. * - Empty strings return `false`, non-empty strings return `true`. * - Numbers: `0` is `false`, others `true`. * - Booleans returned as-is. * - Arrays: `[]` is `false`, non-empty is `true`. * - Other objects: uses `Boolean(value)`, so `{}` is `true`. * * @param {unknown} [value] - The value to be converted. * @returns {boolean} `true` if the value is truthy, otherwise `false`. * * @example * toBooleanLoose(null); // false * toBooleanLoose(""); // false * toBooleanLoose("abc"); // true * toBooleanLoose(0); // false * toBooleanLoose(42); // true * toBooleanLoose([]); // false * toBooleanLoose([1]); // true * toBooleanLoose({}); // true * toBooleanLoose({ a: 1 }); // true */ declare const toBooleanLoose:(value?:unknown)=>boolean; /** * ---------------------------------------------------------- * * ***Extracts digits from a string or number input.*** * ---------------------------------------------------------- * * ✅ Converts the input to a string, trims whitespace, and removes any characters * that are not digits (`0-9`). * * ✅ Returns the cleaned numeric value as a `number`. * * 🚩 If the input is `null`, `undefined`, or results in no digits, * it safely returns `0`. * * @param {string | number | null | undefined} value * The value to process. Accepts a string, number, `null`, or `undefined`. * * @returns {number} * The numeric value after extracting digits. * Returns `0` if input is invalid or contains no digits. * * @example * extractDigits("123abc456"); // ➔ 123456 * extractDigits("$1,234.56"); // ➔ 123456 * extractDigits("9A8B7C6"); // ➔ 9876 * extractDigits("abc"); // ➔ 0 * extractDigits(undefined); // ➔ 0 * extractDigits(null); // ➔ 0 * extractDigits(12345); // ➔ 12345 * extractDigits(" 00a "); // ➔ 0 */ declare const extractDigits:(value?:string | number | null)=>number; /** ------------------------------------------------------------- * * Parses a human-friendly currency string into a JavaScript number. * ------------------------------------------------------------- * * 🚀 Supports multi-locale formats: * * - European: "15.000,10" ➔ 15300.10 * - US: "15,000.10" ➔ 15300.10 * - Swiss: "15'000.10" ➔ 15300.10 * - French: "15 000,10" ➔ 15300.10 * - Indian: "1,23,456.78" ➔ 123456.78 * - Compact: "15300000,10" ➔ 15300000.10 * * ✅ Features: * - Strips symbols automatically: "Rp", "$", "EUR", etc. * - Handles bracket negatives: "(15.000,10)" ➔ -15300.10 * - Normalizes decimal separator (last dot or comma). * - Detects non-breaking spaces (\u00A0, \u202F) often in European data. * - Fallback to 0 for empty, invalid, or non-numeric strings. * * 🔍 How it parses internally: * 1. Removes all characters except digits, ., ,, ', spaces. * 2. Detects bracket (...) as negative. * 3. If Indian style (1,23,456) detected by multiple ,\d{2}, removes all commas. * 4. Otherwise: * - If multiple dots & no commas ➔ thousands: removes all . * - If multiple commas & no dots ➔ thousands: removes all , * - If mixed, treats last , or . as decimal * 5. Converts final decimal to . for JS float. * * 🛠 Gotchas: * - If both . and , are present, last occurrence is used as decimal. * - For strings like "1.121.234,56" ➔ decimal is ,. * - For "1,121,234.56" ➔ decimal is .. * - For "15300000,2121" ➔ decimal becomes . internally. * * @param {string} input * Any messy currency string. May contain: * - currency symbols (Rp, $, CHF, EUR) * - thousands separators (.,', space, \u00A0, \u202F) * - various decimal formats (, or .) * - bracket negative: "(15.000,10)" * * @returns {number} * JavaScript float representation. * Will return 0 for invalid, empty, or non-string input. * * 📦 Examples of input ➔ output: * @example * parseCurrencyString("Rp 15.300.000,21"); * // ➔ 15300000.21 * * parseCurrencyString("15 300 000,21"); * // ➔ 15300000.21 * * parseCurrencyString("CHF 15'300'000.21"); * // ➔ 15300000.21 * * parseCurrencyString("$15,300,000.21"); * // ➔ 15300000.21 * * parseCurrencyString("(15.000,10)"); * // ➔ -15000.10 * * parseCurrencyString("1,23,456.78"); * // ➔ 123456.78 * * parseCurrencyString("15300000,2121"); * // ➔ 15300000.2121 * * parseCurrencyString("USD 15 300 000.21"); * // ➔ 15300000.21 * * parseCurrencyString(""); * // ➔ 0 * * parseCurrencyString("abc"); * // ➔ 0 * * @description * * Notes: * - Use this function as a first step to **sanitize currency inputs** * before storing into database or doing math. * - Always pair this with your formatter for consistent output display. */ declare const parseCurrencyString:(input?:string | null)=>number; /** ---------------------------------------------------------- * * ***Converts a value from a string to its natural JavaScript type.*** * ---------------------------------------------------------- * * ✅ Supported conversions: * - `"true"` → `true` * - `"false"` → `false` * - `"null"` → `null` * - `"undefined"` → `undefined` * - `"42"` → `42` (number) * - `"3.14"` → `3.14` (number) * - `"3,567,890.14"` → `3567890.14` (number) * - `" "` → `""` (trimmed) * - Other strings are returned trimmed & lowercased. * - Non-string inputs are returned unchanged. * * @example * convertType("true") // → true * convertType(" 42 ") // → 42 * convertType("FALSE") // → false * convertType(" null ") // → null * convertType(" ") // → "" * convertType(100) // → 100 * convertType({}) // → {} * * @param {any} value - The value to convert (usually string or unknown type). * @returns {any} The converted JavaScript type (boolean, number, null, undefined, or original). */ declare const convertType:(value:unknown)=>unknown;type NonJsonParsableType=Omit<Exclude<unknown,string | null | undefined>,string>;type Contains<T,U>=[Extract<T,U>] extends [never] ? false:true;type UnknownValue={undefined:true;};type SafeJsonParseResult<TData,T>=IfNotExtends<T,NonJsonParsableType>extends true ? T extends never ? undefined:T extends void ? undefined:T extends number ? undefined:Contains<T,string>extends true ? Contains<T,null & string>extends true ? TData | null | undefined:TData | undefined:IfExtends<T,null>extends true ? null:IfNotExtends<T,NonJsonParsableType>extends true ? TData | null | undefined:undefined:Contains<T,string>extends true ? IsAny<T>extends true ? TData | undefined | null:TData | undefined:undefined;interface CleanParsedDataOptions{ /** Convert numeric strings to numbers (e.g., `"42"` → `42`). * * @default false */ convertNumbers?:boolean; /** Convert `"true"` / `"false"` strings to boolean values. * * @default false */ convertBooleans?:boolean; /** Convert valid date strings into `Date` objects. * * @default false */ convertDates?:boolean; /** Custom date formats to be parsed (e.g., `["DD/MM/YYYY", "MM/DD/YYYY"]`). * * @default [] */ customDateFormats?:string[]; /** Remove `null` values from objects and arrays. * * @default false */ removeNulls?:boolean; /** * Remove `undefined` values from objects and arrays. * * - `false` (default): replaces `undefined` with `null` * - `true`: removes keys with `undefined` values */ removeUndefined?:boolean; /** Remove empty objects `{}` from the final output. * * @default false */ removeEmptyObjects?:boolean; /** Remove empty arrays `[]` from the final output. * * @default false */ removeEmptyArrays?:boolean; /** Strict mode: Removes values that do not match selected conversions. * * @default false */ strictMode?:boolean; /** Enable error logging if JSON parsing fails. * * @default false */ loggingOnFail?:boolean; /** Custom error handler function. * * @default undefined */ onError?:(error:unknown)=>void;} /** -------------------------------------------------- * * ***Cleans parsed JSON data based on provided options.*** * -------------------------------------------------- * * @template T - Expected output type. * @param {unknown} data - The parsed JSON data. * @param {CleanParsedDataOptions} options - Cleaning options. * @returns {T | undefined} - The cleaned data. * * **Note: If using `convertDates`, result may contain Date objects. You may need type assertions in strict TypeScript settings.** * * @example * // Convert numbers and remove nulls * const result = cleanParsedData({ age: "25", name: null }, { convertNumbers: true, removeNulls: true }); * console.log(result); // Output: { age: 25 } * * @example * // Convert boolean strings * const result = cleanParsedData({ isActive: "true" }, { convertBooleans: true }); * console.log(result); // Output: { isActive: true } */ declare const cleanParsedData:<T=unknown>(data:T,options?:CleanParsedDataOptions)=>T | undefined | null; /** -------------------------------------------------- * * ***Parses custom date formats like "DD/MM/YYYY" or "MM/DD/YYYY".*** * -------------------------------------------------- * * @param {string} dateString - Date string to parse. * @param {string} format - Date format to match. * @returns {Date | null} - Returns a Date object if valid, otherwise null. */ declare const parseCustomDate:(dateString:string,format:string)=>Date | null; /** -------------------------------------------------- * * ***Safely parses JSON while handling errors and applying transformations.*** * -------------------------------------------------- * * - ✅ **Supports generics** to ensure accurate return type inference. * - Always provide both `<TData, TInput>` for best results. * - ***Scroll down for full generic behavior explanation.*** * - ✅ Automatically parses valid JSON strings into objects, arrays, numbers, etc. * - ✅ Supports data transformation via options (e.g., convert strings to numbers, booleans, or dates). * - ✅ Returns: * 1. `null` → if input is explicitly `null`. * 2. `undefined` → if input is `undefined`, not a string, or if parsing fails. * 3. Parsed and cleaned result (`TData`) → if input is a valid JSON string. * * ⚠ **JSON.stringify note**: If the input JSON string was created using `JSON.stringify()`, any properties with * `undefined` values would have been automatically removed or converted to `null` depending on the serializer. * Example: * ```ts * JSON.stringify({ a: undefined, b: 1 }); // → '{"b":1}' * JSON.parse('{"a": undefined, "b": 1}') // ❌ invalid JSON * * safeJsonParse('{"name": "John", "score": undefined}'); * // result → { name:"John", score:null } ← because `undefined` is not valid JSON, gets replaced * ``` * Therefore, if you see `undefined` in raw input, it will likely throw unless pre-cleaned or replaced with `null`. * @template TData - The expected output type after parsing and cleaning. * @template TInput - The input value type, used for advanced type inference and return typing. * * @param {TInput} value - The JSON string or value to parse. * @param {CleanParsedDataOptions} [options] - Options to clean, convert types, enable strict mode, * support custom date formats, enable logging, or handle errors via callback. * * @returns {SafeJsonParseResult<TData, TInput>} Parsed and optionally cleaned result, or `null`/`undefined`. * * @throws {TypeError} If `options` is provided but not a valid object. * * @example * 1. ***Basic parse with number & boolean conversion:*** * ```ts * const result = safeJsonParse('{"age": "30", "isActive": "true"}', { * convertNumbers: true, * convertBooleans: true * }); * // result → { age: 30, isActive: true } * ``` * 2. ***Handling `undefined` in input string (manually written, not JSON.stringify):*** * ```ts * const result = safeJsonParse('{"score": undefined}'); * // result → { score: null } ← because `undefined` is not valid JSON, gets replaced * ``` * * 3. ***Strict mode (removes invalid values):*** * ```ts * const result = safeJsonParse('{"name": " ", "score": "99abc"}', { * convertNumbers: true, * strictMode: true * }); * // result → {} * * const result2 = safeJsonParse('{"name": " ", "score": undefined}'); * // result2 → { name:"",score: null } * ``` * * 4. ***Custom date format parsing:*** * ```ts * const result = safeJsonParse('{"birthday": "25/12/2000"}', { * convertDates: true, * customDateFormats: ["DD/MM/YYYY"] * }); * // result → { birthday: new Date("2000-12-25T00:00:00.000Z") } * ``` * * 5. ***Invalid JSON with custom error handling:*** * ```ts * safeJsonParse("{invalid}", { * loggingOnFail: true, * onError: (err) => console.log("Custom handler:", err.message) * }); * // → Logs parsing error and invokes handler * ``` * * 6. ***Null or non-string input returns null/undefined:*** * ```ts * safeJsonParse(null); // → null * safeJsonParse(undefined); // → undefined * safeJsonParse(123); // → undefined * ``` * * 7. ***Generic usage: Provide both output and input type to ensure correct return typing:*** * ```ts * type UserType = { name: string }; * * const obj = JSON.stringify({ * name: "John" * }); * * const toParse = isAuth() ? obj : null; * const toParse2 = isAuth() ? obj : undefined; * * // * `Without Generic`: * const parsed = safeJsonParse(toParse); * //- runtime: { name: "John" } | undefined | null * //- type: Record<string, unknown> | undefined | null * const parsed2 = safeJsonParse(toParse); * //- runtime: { name: "John" } | undefined * //- type: Record<string, unknown> | undefined * * // * `With Generic`: * const parsed = safeJsonParse<UserType>(toParse); * //- runtime: { name: "John" } | undefined | null * //- type: undefined ← (⚠ unexpected!) * const parsed2 = safeJsonParse<UserType>(toParse); * //- runtime: { name: "John" } | undefined * //- type: undefined ← (⚠ unexpected!) * const parsed = safeJsonParse<UserType, typeof toParse>(toParse); * //- runtime: { name: "John" } | null | undefined * //- type: UserType | null | undefined * const parsed2 = safeJsonParse<UserType, typeof toParse>(toParse); * //- runtime: { name: "John" } | undefined * //- type: UserType | undefined * ``` * @note * ⚠ **Generic Behavior:** * - This function supports advanced generic inference for clean, type-safe return values. * - If only the first generic (`TData`) is provided and the second (`TInput`) is omitted, * then `TInput` defaults to `undefined`, resulting in a return type of `undefined`. * - To ensure correct return typing, **always pass both generics** when `value` is dynamic, * nullable, or unioned: `safeJsonParse<TData, typeof value>(value)`. * - This makes the returned type exactly match your expectation: `TData | null | undefined`. */ declare function safeJsonParse<TData extends Record<string,any>=Record<string,unknown>,TInput extends UnknownValue=UnknownValue>(value:TInput,options?:CleanParsedDataOptions):IsAny<TInput>extends true ? TData | null | undefined:undefined;declare function safeJsonParse<TData extends Record<string,any>=Record<string,unknown>,TInput extends string | null | undefined | unknown=undefined>(value:TInput,options?:CleanParsedDataOptions):SafeJsonParseResult<TData,TInput>;type Prev=[never,RangeNumberTo999<1,40>];type DotPath<T,Prefix extends string="",Depth extends number=RangeNumberTo999<1,40>>=Depth extends never ? never:T extends(infer U)[] ? U extends object ? DotPath<U,`${Prefix}`,Prev[Depth]>:never:T extends object ?{[K in Extract<keyof T,string>]:T[K] extends object ? DotPath<T[K],`${Prefix}${K}.`,Prev[Depth]>| `${Prefix}${K}`:`${Prefix}${K}`;}[Extract<keyof T,string>]:never;type ConfigRemoveObjectPaths<T>={key:DotPath<T>;deep?:boolean;}; /** ------------------------------------------------------------------------ * * ***Deletes multiple keys (shallow or deeply nested) from an object.*** * ------------------------------------------------------------------------ * * ✅ Features: * - Removes one or more keys from an object based on their paths (supports dot notation for nested). * - Can delete deeply from all matching nested levels (even inside arrays) when `deep: true`. * - By default does **not mutate** the original object. Clones it first. * Set `deepClone = false` to mutate in place (useful for performance on large data). * - Ensures type safety on `key` paths via `DotPath<T>`, reducing accidental invalid paths. * * 🔍 Behavior: * - When `deep: false` (default), only deletes the direct property at the specified path. * - When `deep: true`, searches deeply and recursively deletes the key from all levels, * including inside arrays of objects (applies the *same* path repeatedly). * - Can delete nested properties safely without throwing even if intermediate objects are missing. * * 🚀 Edge Handling: * - Ignores invalid intermediate objects (will just skip that branch). * - If `object` is `null` or not an object, returns an empty object. * - Throws if `keysToDelete` is not a proper array of `{ key, deep? }` objects. * * @template T - The shape of the input object, used for type-safe dot paths. * * @param {T} object - The object to remove keys from. Must be an object or will return `{}`. * @param {Array<{ key: DotPath<T>, deep?: boolean }>} keysToDelete - * An array of instructions: * - `key`: A string path using dot notation (e.g. `"user.profile.name"`). * - `deep`: If `true`, will recursively remove all instances of the key path at any depth. * @param {boolean} [deepClone=true] - * Whether to deep clone the original object before modifying. * - `true` (default): returns a *new object* with the specified keys removed. * - `false`: modifies the original object in place and returns it. * * @returns {Partial<T>} * - A new object with specified keys removed if `deepClone` is `true`. * - The *same mutated object* if `deepClone` is `false`. * * @throws {TypeError} * - If `object` is not an object. * - If `keysToDelete` is not an array of `{ key, deep? }` objects. * * @example * // 🟢 Shallow deletion * removeObjectPaths( * { a: 1, b: 2, c: { d: 3 } }, * [{ key: "b" }] * ); * // => { a: 1, c: { d: 3 } } * * @example * // 🟢 Nested deletion (shallow, removes only exact path) * removeObjectPaths( * { user: { profile: { name: "Alice", age: 30 } } }, * [{ key: "user.profile.age" }] * ); * // => { user: { profile: { name: "Alice" } } } * * @example * // 🔥 Deep deletion (recursively removes key from all levels and arrays) * removeObjectPaths( * { items: [{ price: 10 }, { price: 20, details: { price: 30 } }] }, * [{ key: "price", deep: true }] * ); * // => { items: [{}, { details: {} }] } * * @example * // 📝 Without cloning: mutates original object * const obj = { x: 1, y: 2 }; * removeObjectPaths(obj, [{ key: "y" }], false); * console.log(obj); // => { x: 1 } * * @example * // 🚫 Invalid usage throws * removeObjectPaths(42, [{ key: "a" }]); * // => throws TypeError */ declare const removeObjectPaths:<T extends Record<string,unknown>>(object:T,keysToDelete:ConfigRemoveObjectPaths<T>[],deepClone?:boolean)=>Partial<T>; /** -------------------------------------------- * * ***Safely converts a JavaScript value into a stable, JSON-compatible string.*** * -------------------------------------------- * * Features: * - Recursively sorts object keys if `sortKeys` is true, to ensure stable key order. * - Optionally sorts array values if `ignoreOrder` is true (only sorts shallow primitives inside arrays). * - Removes functions and symbols (they are omitted from the output). * - Converts `undefined`, `NaN`, `Infinity`, `-Infinity` to `null`. * - Converts `BigInt` to a string (since JSON does not support it). * - Handles circular references by replacing them with the string `"[Circular]"`. * - Serializes: * - `Date` instances as ISO strings. * - `Map` as `{ map: [ [key, value], ... ] }`. * - `Set` as `{ set: [values...] }`. * * Compared to `JSON.stringify`, this ensures **stable output**: * - Same object structure always produces the same string. * - Useful for deep equality checks, hashing, caching keys, or snapshot tests. * * @param {unknown} value * The value to serialize. Can be primitives, objects, arrays, Maps, Sets, Dates, etc. * * @param {boolean} [sortKeys=true] * Whether to sort object keys alphabetically (recursively). If `false`, preserves original insertion order. * * @param {boolean} [ignoreOrder=false] * Whether to sort array primitive values. When `true`: * - Only primitive values in arrays are sorted. * - Objects and nested arrays keep their position and are placed after sorted primitives. * If `false`, arrays retain their original order. * * @param {boolean} [pretty=false] * If `true`, output is formatted with 2-space indentation and newlines (pretty-printed). * If `false`, produces compact single-line JSON. * * @returns {string} * A stable JSON string representation of the input value. * * @throws {TypeError} * Throws if `sortKeys`, `ignoreOrder`, or `pretty` are not strictly boolean. * * @example * // Basic object key sorting * safeStableStringify({ b: 2, a: 1 }); * // => '{"a":1,"b":2}' * * @example * // Disable key sorting (preserve insertion order) * safeStableStringify({ b: 2, a: 1 }, false); * // => '{"b":2,"a":1}' * * @example * // Sorting arrays * safeStableStringify([3, 1, 2], true, true); * // => '[1,2,3]' * * @example * // Nested object + ignoreOrder=true * safeStableStringify({ z: [3, 1, 2], x: { d: 4, c: 3 } }, true, true); * // => '{"x":{"c":3,"d":4},"z":[1,2,3]}' * * @example * // sortKeys=false and ignoreOrder=true * safeStableStringify({ z: [3, 1, 2], x: { d: 4, c: 3 } }, false, true); * // => '{"z":[1,2,3],"x":{"d":4,"c":3}}' * * @example * // pretty print output * safeStableStringify([3, 1, 2], true, true, true); * // => `[ * // 1, * // 2, * // 3 * // ]` * * @example * // Handles Date, BigInt, Map and Set * safeStableStringify({ * time: new Date("2025-01-01"), * big: BigInt(9007199254740991), * data: new Map([["key", new Set([1, 2])]]) * }); * // => '{"big":"9007199254740991","data":{"map":[["key",{"set":[1,2]}]]},"time":"2025-01-01T00:00:00.000Z"}' * * @example * // Functions and symbols are removed * safeStableStringify({ f: () => {}, s: Symbol("wow") }); * // => '{}' * * @example * // undefined, NaN, Infinity convert to null * safeStableStringify([undefined, NaN, Infinity, -Infinity]); * // => '[null,null,null,null]' * * @example * // Circular reference * const obj = { name: "A" }; * obj.self = obj; * safeStableStringify(obj); * // => '{"name":"A","self":"[Circular]"}' * * @example * // Complex nested ignoreOrder with objects * const arr = [9, 7, [4, 2, 3], { z: [5, 1, 6] }]; * safeStableStringify(arr, true, true); * // => '[7,9,[2,3,4],{"z":[1,5,6]}]' */ declare const safeStableStringify:(value:unknown,sortKeys?:boolean,ignoreOrder?:boolean,pretty?:boolean)=>string; /** ---------------------------------------------------------- * * ***Recursively converts a value into a string based on the `forceToString` option.*** * ---------------------------------------------------------- * * - `"stringOrNumber"`: Converts strings and numbers to strings. * - `"primitives"`: Converts all primitives (number, string, boolean, bigint, undefined, null, NaN) to strings. * - `"all"`: Converts everything, including symbols, functions, Dates, RegExp, Maps, Sets, Errors, Promises, * and deeply all object properties, to strings. * - `false` (default): Leaves everything unchanged. * * Special behaviors: * - `NaN` → `"NaN"` only in `"primitives"` or `"all"` mode. * - `Date` → ISO string only in `"all"` mode. * - `RegExp` → Source string (e.g. `/abc/i`) only in `"all"` mode. * - `Symbol` → `Symbol(description)` string only in `"all"` mode. * - `Map` → Array of [key, value] pairs with keys/values stringified deeply (only in `"all"` mode). * - `Set` → Array of values stringified deeply (only in `"all"` mode). * - `Function` → Source code string (e.g. `"() => 1"`) only in `"all"` mode. * - `Error`, `Promise` → Stringified via `.toString()` only in `"all"` mode. * * * @param {unknown} value - The value to process. Can be anything: primitive, array, object, function, etc. * @param {false | "stringOrNumber" | "primitives" | "all"} forceToString - The mode of string conversion. * @returns {unknown} A new value with the conversion applied based on `forceToString`. * * @example * toStringDeepForce(42, "stringOrNumber"); * // => "42" * * @example * toStringDeepForce(true, "primitives"); * // => "true" * * @example * toStringDeepForce(null, "primitives"); * // => "null" * * @example * toStringDeepForce(Symbol("x"), "all"); * // => "Symbol(x)" * * @example * toStringDeepForce({ a: 1, b: [2, NaN] }, "primitives"); * // => { a: "1", b: ["2", "NaN"] } * * @example * toStringDeepForce(new Date("2025-01-01"), "all"); * // => "2025-01-01T00:00:00.000Z" * * @example * toStringDeepForce(() => 1, "all"); * // => "() => 1" * * @example * toStringDeepForce(/abc/i, "all"); * // => "/abc/i" * * @example * toStringDeepForce(new Map([["a", 1], ["b", 2]]), "all"); * // => [["a", "1"], ["b", "2"]] * * @example * toStringDeepForce(new Set([1, 2, 3]), "all"); * // => ["1", "2", "3"] * * @example * toStringDeepForce(new Error("Oops"), "all"); * // => "Error: Oops" * * @example * toStringDeepForce(Promise.resolve(1), "all"); * // => "[object Promise]" * * @example * toStringDeepForce({ func: () => 123 }, "all"); * // => { func: "() => 123" } * * @example * toStringDeepForce([1, "a", { b: 2 }], false); * // => [1, "a", { b: 2 }] */ declare const toStringDeepForce:(value:unknown,forceToString:false | "stringOrNumber" | "primitives" | "all")=>unknown;type ConvertedDeepNumber<T,RemoveEmptyObjects extends boolean,RemoveEmptyArrays extends boolean>=T extends null | undefined ? never:T extends number | `${number}` ? number:T extends any[] ? ConvertedDeepNumber<T[number],RemoveEmptyObjects,RemoveEmptyArrays>[]:T extends Record<string,unknown>?{[K in keyof T]:ConvertedDeepNumber<T[K],RemoveEmptyObjects,RemoveEmptyArrays>;}extends infer O ? RemoveEmptyObjects extends true ? keyof O extends never ? never:O:O:never:never; /** -------------------------------------------------- * * ***Converts deeply nested arrays or objects into number while preserving structure.*** * -------------------------------------------------- * * Features: * - ✅ Removes `null`, `undefined`, NaN, Infinity, and non-numeric values. * - 🔄 Recursively processes nested objects and arrays. * - 🔢 Converts valid number, including decimals (e.g. `"3.5"` → `3.5`). * - 🧹 Can remove empty objects `{}` or arrays `[]` based on flags. * * @template T - The input data type (Array, Object, etc) * @template RemoveEmptyObjects - Whether to remove empty objects * @template RemoveEmptyArrays - Whether to remove empty arrays * * @param {T} input - The data to convert * @param {boolean} [removeEmptyObjects=false] - Remove empty objects `{}` if `true` * @param {boolean} [removeEmptyArrays=false] - Remove empty arrays `[]` if `true` * * @returns {ConvertedDeepNumber<T, RemoveEmptyObjects, RemoveEmptyArrays> | undefined} * The transformed data, or `undefined` if entirely empty after processing. * * @example * toNumberDeep("123") // → 123 * toNumberDeep("12.34") // → 12.34 * toNumberDeep("not number") // → undefined * * @example * toNumberDeep([NaN, Infinity, -Infinity, "10"]) * // → [10] * * @example * toNumberDeep({ a: {}, b: [] }, false, false) * // → { a: {}, b: [] } * * @example * toNumberDeep({ a: {}, b: [] }, true, false) * // → { b: [] } * * @example * toNumberDeep({ a: {}, b: [] }, false, true) * // → { a: {} } * * @example * toNumberDeep({ a: {}, b: [], c: { d: null } }, true, true) * // → {} * * @example * toNumberDeep({ * a: "1", * b: { * c: "not num", * d: ["2", "3.5", null, { e: "4.4", f: "invalid" }], * }, * g: [], * }) * // → { a: 1, b: { d: [2, 3.5, { e: 4.4 }] }, g: [] } * * @example * toNumberDeep({ x: {}, y: [], z: [{ a: {}, b: [] }] }, false, true) * // → { x: {}, z: [{ a: {} }] } * * @example * toNumberDeep({ x: {}, y: [], z: [{ a: {}, b: [] }] }, true, false) * // → { y: [], z: [{ b: [] }] } * * @example * toNumberDeep({ * x: {}, * y: [], * z: [{ a: {}, b: [], c: "3" }, { d: "4.5" }] * }, true, true) * // → { z: [{ c: 3 }, { d: 4.5 }] } * * @example * toNumberDeep([[[[[["1"]]], null]], "2", "abc"], false, true) * // → [[[[[[1]]]]], 2] * * @example * toNumberDeep(["1", {}, [], ["2", {}, []]], true, true) * // → [1, [2]] * * @example * toNumberDeep(["1", () => {}, Symbol("wow"), "2"]) * // → [1, 2] * * @example * toNumberDeep({ a: { b: {} } }, false, true) * // → { a: { b: {} } } * * @example * toNumberDeep(["1", { a: {} }], true) * // → [1] * * @example * toNumberDeep(["1", { a: {} }], false) * // → [1, { a: {} }] * * @example * toNumberDeep(["1", [], { a: [] }], false, false) * // → [1, [], { a: [] }] */ declare const toNumberDeep:<T extends unknown,RemoveEmptyObject