@gmana/utils
Version:
Utility functions for React and TypeScript projects.
742 lines • 24.9 kB
TypeScript
//#region src/absolute-url.d.ts
/**
* Creates an absolute URL by combining a base URL with a relative path.
*
* @param path - The relative path to append to the base URL. Can be null, undefined, or empty.
* @param options - Optional configuration for URL generation.
* @returns The absolute URL string.
*
* @example
* ```typescript
* absoluteUrl("/api/users") // "https://example.com/api/users"
* absoluteUrl("api/users") // "https://example.com/api/users"
* absoluteUrl("") // "https://example.com"
* absoluteUrl(null) // "https://example.com"
* absoluteUrl("/api/users", { query: { id: "123" } }) // "https://example.com/api/users?id=123"
* absoluteUrl("/api/users", { fragment: "section1" }) // "https://example.com/api/users#section1"
* ```
*/
declare function absoluteUrl(path?: string | null, options?: {
query?: Record<string, string | number | boolean | null | undefined>;
fragment?: string;
baseUrl?: string;
}): string;
//#endregion
//#region src/bytes.d.ts
type ByteUnit = "b" | "kb" | "mb" | "gb" | "tb" | "pb" | "k" | "m" | "g" | "t" | "p";
type ByteInput = `${number}${ByteUnit}` | `${number}` | number;
type ByteBase = 1000 | 1024;
interface ByteConvertOptions {
/** Base for calculations: 1024 (binary) or 1000 (decimal). Default: 1024 */
base: ByteBase;
/** Whether to round the result to the nearest integer. Default: true */
round: boolean;
}
interface FormatBytesOptions {
base?: ByteBase;
precision?: number;
/** Use full unit names e.g. "bytes", not "B". Default: false */
verbose?: boolean;
}
declare const BYTE_REGEX: RegExp;
/**
* Converts a byte string or number to raw bytes.
*
* @example
* toBytes("1kb") // 1024
* toBytes("1mb", { base: 1000 }) // 1000000
* toBytes("2.5gb") // 2684354560
* toBytes(1024) // 1024
*/
declare function toBytes(input: ByteInput, options?: Partial<ByteConvertOptions>): number;
/**
* Formats a raw byte count into a human-readable string.
*
* @example
* formatBytes(1536) // "1.50 KB"
* formatBytes(1500, { base: 1000 }) // "1.50 KB"
* formatBytes(1024, { verbose: true }) // "1.00 KB"
* formatBytes(0) // "0 B"
*/
declare function formatBytes(bytes: number, options?: FormatBytesOptions): string;
/** Creates a pre-configured `toBytes` converter with fixed defaults. */
declare function createByteConverter(defaultOptions?: Partial<ByteConvertOptions>): (input: ByteInput, overrides?: Partial<ByteConvertOptions>) => number;
//#endregion
//#region src/chunk.d.ts
declare const chunk: <T>(array: T[], size: number) => T[][];
//#endregion
//#region src/clsx.d.ts
type ClassValue = string | number | ClassRecord | ClassArray | undefined | null | boolean;
interface ClassRecord {
[key: string]: boolean | undefined | null;
}
type ClassArray = Array<ClassValue>;
/**
* Joins class names together.
*
* Accepts strings, numbers, arrays, or objects mapping keys to booleans.
* Falsy values (false, null, undefined) are ignored.
*
* @example
* clsx("foo", "bar") // "foo bar"
* clsx("foo", { bar: true, baz: false }) // "foo bar"
* clsx(["foo", null, "bar"]) // "foo bar"
* clsx("foo", undefined, "bar") // "foo bar"
*/
declare function clsx(...args: ClassValue[]): string;
//#endregion
//#region src/cn.d.ts
declare const cn: (...inputs: ClassValue[]) => string;
//#endregion
//#region src/compact.d.ts
declare const compact: <T>(array: (T | null | undefined | false | 0 | "")[]) => T[];
//#endregion
//#region src/compact-object.d.ts
interface CompactOptions {
compactArrays?: boolean;
removeEmptyArrays?: boolean;
isEmpty?: (value: unknown) => boolean;
}
declare function compactObject<T extends Record<string, unknown>>(input: T, options?: CompactOptions): Partial<T>;
//#endregion
//#region src/count-by.d.ts
/**
* Counts occurrences of each element in an array
*/
declare const countBy: <T, K extends string | number | symbol>(array: T[], keyFn: (item: T) => K) => Record<K, number>;
//#endregion
//#region src/difference.d.ts
declare const difference: <T>(array1: T[], array2: T[]) => T[];
//#endregion
//#region src/drop.d.ts
/**
* Drops n elements from the beginning of an array
*/
declare const drop: <T>(array: T[], n: number) => T[];
//#endregion
//#region src/drop-right.d.ts
/**
* Drops elements from the end of an array
*/
declare const dropRight: <T>(array: T[], n: number) => T[];
//#endregion
//#region src/flatten.d.ts
/**
* Flattens a nested object or array into a single-level object.
* @param obj The object or array to flatten.
* @param separator The string to use between nested keys.
* @returns A flattened object.
*/
declare const flatten: (obj: Record<string, unknown>, separator?: string) => Record<string, unknown>;
//#endregion
//#region src/flatten-array.d.ts
declare const flattenArray: <T>(array: (T | T[])[]) => T[];
//#endregion
//#region src/flatten-deep-array.d.ts
declare const flattenDeepArray: <T>(array: (T | (T | T[])[])[]) => T[];
//#endregion
//#region src/format-time.d.ts
interface FormatTimeOptions {
/**
* Format style for the time display
* - 'digital': "1:05:30" or "5:30"
* - 'long': "1 hour 5 minutes 30 seconds"
* - 'short': "1h 5m 30s"
* - 'compact': "1:05:30" (always shows hours)
* @default 'digital'
*/
format?: "digital" | "long" | "short" | "compact";
/**
* Always show hours even if 0
* @default false
*/
alwaysShowHours?: boolean;
/**
* Round decimal seconds
* - 'floor': Round down (default)
* - 'ceil': Round up
* - 'round': Round to nearest
* @default 'floor'
*/
roundingMode?: "floor" | "ceil" | "round";
/**
* Show leading zero for minutes when hours are present
* @default true
*/
padMinutes?: boolean;
/**
* Custom separator for digital format
* @default ':'
*/
separator?: string;
}
/**
* Formats seconds into a human-readable time string
*
* @param seconds - The number of seconds to format (must be >= 0)
* @param options - Formatting options
* @returns Formatted time string
*
* @example
* ```typescript
* formatTime(65) // "1:05"
* formatTime(3665) // "1:01:05"
* formatTime(65, { format: 'short' }) // "1m 5s"
* formatTime(65, { format: 'long' }) // "1 minute 5 seconds"
* formatTime(5, { alwaysShowHours: true }) // "0:00:05"
* formatTime(5.7, { roundingMode: 'ceil' }) // "0:06"
* formatTime(65, { separator: '·' }) // "1·05"
* ```
*/
declare function formatTime(seconds: number, options?: FormatTimeOptions): string;
/**
* Parses a formatted time string back to seconds
*
* @param timeString - Time string in format "1:05:30", "1:05", "5:30", etc.
* @param separator - Separator used in the time string
* @returns Number of seconds
*
* @example
* ```typescript
* parseTime("1:05") // 65
* parseTime("1:01:05") // 3665
* parseTime("5:30") // 330
* ```
*/
declare function parseTime(timeString: string, separator?: string): number;
//#endregion
//#region src/get-initial-letter.d.ts
/**
* Generates a one or two-letter initial string from a full name.
* It takes the first letter of the first two name parts.
* This function correctly handles diacritics, extra whitespace, and empty or invalid inputs.
*
* @example
* getInitialLetter("John Doe") // "JD"
* getInitialLetter(" Beyond Knowles-Carter") // "BK"
* getInitialLetter("Cher") // "C"
* getInitialLetter(null) // "?"
*
* @param fullName The full name to process. Can be a string, null, or undefined.
* @returns The uppercase initials (1 or 2 characters), or an empty string if the input is invalid.
*/
declare function getInitialLetter(fullName?: string | null, fallback?: string): string;
//#endregion
//#region src/get-os.d.ts
type OS = "windows" | "macos" | "linux" | "android" | "ios" | "unknown";
declare const osMap: Record<OS, {
type: OS;
label: string;
}>;
declare function getOS(userAgent: string): {
type: OS;
label: string;
};
//#endregion
//#region src/get-token-exp-claim.d.ts
/**
* Extract expiration claim from JWT token
* @param token - JWT token
* @returns expiration timestamp in seconds, or null if not found
*/
declare function getTokenExpClaim(token: string): number | null;
//#endregion
//#region src/group-by.d.ts
declare const groupBy: <T, K extends string | number | symbol>(array: T[], key: (item: T) => K) => Record<K, T[]>;
//#endregion
//#region src/group-consecutive.d.ts
/**
* Creates an array of arrays, grouping consecutive elements by a key function
*/
declare const groupConsecutive: <T, K>(array: T[], keyFn: (item: T) => K) => T[][];
//#endregion
//#region src/intersection.d.ts
declare const intersection: <T>(array1: T[], array2: T[]) => T[];
//#endregion
//#region src/is-array.d.ts
/**
* Checks if the given value is an array.
*/
declare const isArray: (input: unknown) => input is any[];
//#endregion
//#region src/is-boolean.d.ts
/**
* Checks if the given value is a boolean primitive.
*/
declare const isBoolean: (value: unknown) => value is boolean;
//#endregion
//#region src/is-dev.d.ts
/**
* Checks if the current environment is a development environment.
* Returns true if NODE_ENV is 'development' or 'test'.
*/
declare const isDev: boolean;
//#endregion
//#region src/is-empty.d.ts
/**
* Checks if the given value is empty.
*/
declare const isEmpty: (input: unknown) => boolean;
//#endregion
//#region src/is-function.d.ts
/**
* Checks if the given value is a function.
*/
declare const isFunction: (value: unknown) => value is (...args: unknown[]) => unknown;
//#endregion
//#region src/is-navigator.d.ts
/**
* Checks if navigator is available.
*/
declare const isNavigator: boolean;
//#endregion
//#region src/is-number.d.ts
/**
* Checks if the given value is a number.
*/
declare const isNumber: (value: unknown) => boolean;
//#endregion
//#region src/is-object.d.ts
/**
* Checks if the given value is an object.
* Returns true if the value is not null and is of type 'object'.
*/
declare const isObject: (value: unknown) => value is object;
//#endregion
//#region src/is-string.d.ts
/**
* Checks if the given value is a string primitive.
*/
declare const isString: (value: unknown) => value is string;
//#endregion
//#region src/is-symbol.d.ts
/**
* Checks if the given value is a symbol.
*/
declare function isSymbol(value: unknown): boolean;
//#endregion
//#region src/is-token-expired.d.ts
/**
* Is token expired?
*
* @param token - JWT token to check
* @param offsetSeconds - Optional offset in seconds to consider token expired earlier
* @returns true if token is expired or invalid, false if valid
*/
declare function isTokenExpired(token: string, offsetSeconds?: number): boolean;
//#endregion
//#region src/is-undef.d.ts
/**
* Checks if the given value is undefined.
*
* @param value - The value to check.
* @returns Whether the value is undefined.
*/
declare const isUndef: (value: unknown) => value is undefined;
//#endregion
//#region src/is-url.d.ts
/**
* Checks if the given url is valid
* @param url - The url to check
* @returns True if url is valid, false otherwise
*/
declare function isUrl(url: string | URL): boolean;
//#endregion
//#region src/is-valid-component-name.d.ts
/**
* Utility type for component validation results
*/
type ComponentValidationResult = {
valid: boolean;
errors: string[];
};
/**
* Comprehensive validation for component names
* @param name - The component name to validate
* @param options - Validation options
* @returns Validation result with detailed feedback
* @example
* isValidComponentName("my-component") // { valid: true, errors: [] }
* isValidComponentName("") // { valid: false, errors: ["Name cannot be empty"] }
* isValidComponentName("My-Component") // { valid: false, errors: ["Name must be lowercase"] }
*/
declare function isValidComponentName(name: string, options?: {
allowEmpty?: boolean;
minLength?: number;
maxLength?: number;
}): ComponentValidationResult;
//#endregion
//#region src/is-valid-json-string.d.ts
/**
* Checks if the given string is valid JSON.
*
* @param str - The string to check.
* @returns True if the string is valid JSON, false otherwise.
*/
declare function isValidJsonString(str: string): boolean;
//#endregion
//#region src/is-valid-url.d.ts
/**
* Validates if a string is a valid URL.
*
* @param url - The URL string to validate.
* @returns True if the URL is valid, false otherwise.
*
* @example
* ```typescript
* isValidUrl("https://example.com") // true
* isValidUrl("not-a-url") // false
* ```
*/
declare function isValidUrl(url: string): boolean;
//#endregion
//#region src/join-paths.d.ts
/**
* Joins multiple URL path segments together.
*
* @param segments - Array of path segments to join.
* @returns The joined path string.
*
* @example
* ```typescript
* joinPaths(["api", "users", "123"]) // "/api/users/123"
* joinPaths(["", "api", "users"]) // "/api/users"
* ```
*/
declare function joinPaths(segments: (string | null | undefined)[]): string;
//#endregion
//#region src/make-title.d.ts
type TextTemplate = string | ((value: string, site: string) => string);
interface TemplateParams {
disableSuffix?: boolean;
template?: TextTemplate;
}
/**
* Makes a SEO text based on a template
* @param base - The base text to apply the template to
* @param site - The site name to append to the base text
* @param params - The parameters to apply the template to
* @returns
* @example
* ```ts
* const siteName = "Linkiri"
*
* // Title with a custom string template
* const pageTitle = makeTitle("Jobs in Tech", siteName, {
* template: "%s - Powered by Linkiri"
* })
* // -> "Jobs in Tech - Powered by Linkiri"
*
* // Title with a function template
* const fancyTitle = makeTitle("Developers", siteName, {
* template: (title, site) => `${title.toUpperCase()} 👨💻 | ${site}`
* })
* // -> "DEVELOPERS 👨💻 | Linkiri"
*
* // Title with no template (defaults to `base | site`)
* const defaultTitle = makeTitle("Careers", siteName, {})
* // -> "Careers | Linkiri"
*
* // Description example (reuses the same engine)
* const description = makeTitle("Find your dream job fast.", siteName, {
* template: "%s 🚀"
* })
* // -> "Find your dream job fast. 🚀"
*
* // OG title example with suffix disabled
* const ogTitle = makeTitle("Linkiri OG Preview", siteName, {
* disableSuffix: true
* })
* // -> "Linkiri OG Preview"
* ```
*/
declare function makeTitle(base: string, site: string, params: TemplateParams): string;
//#endregion
//#region src/max-by.d.ts
/**
* Finds the maximum element in an array based on a selector function
*/
declare const maxBy: <T>(array: T[], selector: (item: T) => number) => T | undefined;
//#endregion
//#region src/mean-by.d.ts
/**
* Calculates the average of array elements based on a selector function
*/
declare const meanBy: <T>(array: T[], selector: (item: T) => number) => number;
//#endregion
//#region src/min-by.d.ts
/**
* Finds the minimum element in an array based on a selector function
*/
declare const minBy: <T>(array: T[], selector: (item: T) => number) => T | undefined;
//#endregion
//#region src/number.d.ts
declare const toASCII: (s: string) => string;
declare const toKhmer: (s: string) => string;
/**
* @description
* Converts a number to its word representation in English.
* @example
// Example usage:
const doubleNumber = 1234567.99
//result: One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven Point Eight Nine
const wordRepresentation = convertToWord(doubleNumber)
console.log(`${doubleNumber} in words: ${wordRepresentation}`)
*/
declare function numberToWord(n: number): string;
/**
* Converts a number to a string representation in Khmer words.
*
* @param value - The number to convert to words
* @param sep - Separator between number groups, default ' '
* @param del - Decimal point separator, default ' ក្បៀស '
* @returns String representation of the number in Khmer words
* @example
console.log(numberToWordKm(1234567.89))
// result: មួយលាន ពីរសែន បីម៉ឺន បួនពាន់ ប្រាំរយ ហុកសិបប្រាំពីរ ក្បៀស ប្រាំបី ប្រាំបួន
*/
declare function numberToWordKm(value: number, sep?: string, del?: string): string;
/**
* Formats a number with standard suffixes (K, M, B, T, etc.).
*
* @param value - The number to format. If null, undefined, or 0, returns "0"
* @param decimalPlaces - Number of decimal places to include. Defaults to 1
* @returns The formatted number string with appropriate suffix
*
* @example
* formatNumber(1234) // "1.2K"
* formatNumber(1234567, 2) // "1.23M"
* formatNumber(0) // "0"
* formatNumber(-1500) // "-1.5K"
*/
declare function formatNumber(value?: number | null, decimalPlaces?: number): string;
declare const formatCurrency: ({
amount,
currencyCode,
minFractionDigits,
maxFractionDigits,
locale
}: {
amount: number;
currencyCode: string;
minFractionDigits?: number;
maxFractionDigits?: number;
locale?: string;
}) => string;
//#endregion
//#region src/partition.d.ts
declare const partition: <T>(array: T[], predicate: (item: T, index: number) => boolean) => [T[], T[]];
//#endregion
//#region src/pick.d.ts
/**
* Returns a partial copy of an object containing only the keys specified.
* If the key does not exist, the property is ignored.
*/
declare function pick<T extends object, K extends keyof T>(names: readonly K[], obj: T): Pick<T, K>;
declare function pick<T extends object>(names: readonly string[]): (obj: T) => Partial<T>;
//#endregion
//#region src/sample.d.ts
/**
* Returns a random sample of n elements from an array
*/
declare const sample: <T>(array: T[], n?: number) => T[];
//#endregion
//#region src/shuffle.d.ts
/**
* Shuffles an array using Fisher-Yates algorithm
*/
declare const shuffle: <T>(array: T[]) => T[];
//#endregion
//#region src/sort-by.d.ts
/**
* Sorts an array by multiple criteria
*/
declare const sortBy: <T>(array: T[], ...selectors: ((item: T) => unknown)[]) => T[];
//#endregion
//#region src/sum-by.d.ts
/**
* Calculates the sum of array elements based on a selector function
*/
declare const sumBy: <T>(array: T[], selector: (item: T) => number) => number;
//#endregion
//#region src/symmetric-difference.d.ts
declare const symmetricDifference: <T>(array1: T[], array2: T[]) => T[];
//#endregion
//#region src/take.d.ts
/**
* Takes n elements from the beginning of an array
*/
declare const take: <T>(array: T[], n: number) => T[];
//#endregion
//#region src/take-right.d.ts
/**
* Takes elements from the end of an array
*/
declare const takeRight: <T>(array: T[], n: number) => T[];
//#endregion
//#region src/to-case.d.ts
type TransformContext = {
input: string;
words: string[];
};
type TransformStep = (ctx: TransformContext) => TransformContext;
type Formatter = (ctx: TransformContext) => string;
type CaseType = "lowercase" | "uppercase" | "sentence" | "title" | "snake" | "kebab" | "camel" | "pascal" | "dot" | "constant";
type CaseDefinition = {
steps: TransformStep[];
format: Formatter;
};
declare function toCase(input: string, type: CaseType): string;
declare function extendCases(custom: Record<string, CaseDefinition>): void;
//#endregion
//#region src/to-iso.d.ts
declare function toIso(value?: Date | string): string | undefined;
//#endregion
//#region src/truncate-text.d.ts
type TruncateTextOptions = {
maxLength?: number;
ellipsis?: string;
preserveWords?: boolean;
returnUndefinedIfEmpty?: boolean;
};
declare function truncateText(text?: string, options?: TruncateTextOptions): string | undefined;
//#endregion
//#region src/unique.d.ts
declare const unique: <T>(array: T[]) => T[];
//#endregion
//#region src/unique-by.d.ts
declare const uniqueBy: <T, K>(array: T[], keyFn: (item: T) => K) => T[];
//#endregion
//#region src/v-card.d.ts
/**
* VCard Generator - A utility for creating vCard 4.0 format contact cards
* Supports social media, messaging platforms, and comprehensive contact information
*/
interface ISocialMedia {
facebook?: string;
twitter?: string;
linkedin?: string;
instagram?: string;
youtube?: string;
github?: string;
}
interface IMessagingPlatforms {
telegram?: string;
whatsapp?: string;
messenger?: string;
skype?: string;
discord?: string;
}
interface IAddress {
type?: "home" | "work" | "other";
street?: string;
city?: string;
state?: string;
postalCode?: string;
country?: string;
}
interface VCardContact {
firstName?: string;
lastName?: string;
nickname?: string;
organization?: string;
title?: string;
department?: string;
email?: string | string[];
phone?: string | string[];
mobile?: string | string[];
fax?: string | string[];
address?: IAddress[];
website?: string;
birthday?: Date;
photo?: string;
social?: ISocialMedia;
messaging?: IMessagingPlatforms;
categories?: string[];
note?: string;
}
/**
* Utility class for generating vCard 4.0 format contact cards
*/
declare class VCardGenerator {
private static readonly VCARD_VERSION;
private static readonly SOCIAL_PLATFORMS;
private static readonly MESSAGING_PLATFORMS;
/**
* Escapes special characters for vCard format
* @param value - String to escape
* @returns Escaped string safe for vCard format
*/
private static escapeVCard;
/**
* Formats a date to vCard BDAY format (YYYYMMDD)
* @param date - Date to format
* @returns Formatted date string
*/
private static formatDate;
/**
* Formats email addresses for vCard
* @param emails - Single email or array of emails
* @returns Array of formatted email lines
*/
private static formatEmails;
/**
* Formats address information for vCard
* @param address - Address object
* @returns Formatted address line
*/
private static formatAddress;
/**
* Formats social media profiles for vCard
* @param social - Social media object
* @returns Array of formatted social media lines
*/
private static formatSocialMedia;
/**
* Formats messaging platform information for vCard
* @param messaging - Messaging platforms object
* @returns Array of formatted messaging lines
*/
private static formatMessaging;
/**
* Formats phone numbers for vCard
* @param values - Phone number(s)
* @param type - Phone type (WORK,VOICE | CELL,VOICE | FAX)
* @returns Array of formatted phone lines
*/
private static formatPhones;
/**
* Formats photo data for vCard
* @param photo - Photo URL or base64 data
* @returns Formatted photo line or null
*/
private static formatPhoto;
/**
* Validates contact data before generating vCard
* @param contact - Contact object to validate
* @throws Error if contact data is invalid
*/
private static validateContact;
/**
* Generates a vCard 4.0 string from contact information
* @param contact - Contact information object
* @returns vCard formatted string
* @throws Error if contact data is invalid
*/
static generate(contact: VCardContact): string;
/**
* Creates a downloadable blob for the vCard
* @param contact - Contact information
* @returns Blob object for download
*/
static createDownloadBlob(contact: VCardContact): Blob;
}
//#endregion
//#region src/zip.d.ts
/**
* Zips multiple arrays together
*/
declare const zip: <T extends readonly unknown[][]>(...arrays: T) => Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }>;
//#endregion
export { BYTE_REGEX, ByteBase, ByteConvertOptions, ByteInput, ByteUnit, CaseType, ClassArray, ClassRecord, ClassValue, ComponentValidationResult, FormatBytesOptions, FormatTimeOptions, type IAddress, type IMessagingPlatforms, type ISocialMedia, OS, TemplateParams, TextTemplate, type VCardContact, VCardGenerator, absoluteUrl, chunk, clsx, cn, compact, compactObject, countBy, createByteConverter, difference, drop, dropRight, extendCases, flatten, flattenArray, flattenDeepArray, formatBytes, formatCurrency, formatNumber, formatTime, getInitialLetter, getOS, getTokenExpClaim, groupBy, groupConsecutive, intersection, isArray, isBoolean, isDev, isEmpty, isFunction, isNavigator, isNumber, isObject, isString, isSymbol, isTokenExpired, isUndef, isUrl, isValidComponentName, isValidJsonString, isValidUrl, joinPaths, makeTitle, maxBy, meanBy, minBy, numberToWord, numberToWordKm, osMap, parseTime, partition, pick, sample, shuffle, sortBy, sumBy, symmetricDifference, take, takeRight, toASCII, toBytes, toCase, toIso, toKhmer, truncateText, unique, uniqueBy, zip };
//# sourceMappingURL=index.d.ts.map