primitiveprimer
Version:
Bluntly extend String, Array, Number, Object prototypes with useful methods, or use them as standalone utilities while leaving prototypes untouched
255 lines (251 loc) • 11.7 kB
TypeScript
type NonEmpty = string | any[] | Record<string, unknown> | number | boolean;
interface PrimeString {
/** Replace the file extension with `ext`. */
changeExtension(ext: string): string;
/** Return the string reversed. */
reverse(): string;
/** Convert the string to Title Case. */
toTitleCase(): string;
/** Split string into words. */
words(): string[];
/** Reverse slashes relative to `str`. */
slashreverse(str: string): string;
/** Convert slashes to Windows style. */
slashwin(): string;
/** Convert slashes to POSIX style. */
slashlinux(): string;
/** Trim whitespace from both ends. */
strip(): string;
/** Return true if contains any of the provided substrings. */
containsAny(...arr: string[]): boolean;
/** Create a URL/file-system safe slug. */
toSlug(): string;
/** Compare strings after stripping/normalizing. */
stripCompare(other: string): boolean;
/** Capitalize each word in the string. */
toWordCapitalized(): string;
/** Truncate to `length`, appending optional `suffix`. */
truncate(length: number, suffix?: string): string;
/** Return true if string contains valid JSON. */
isJson(): boolean;
/** Convert string to camelCase. */
toCamelCase(): string;
/** Parse JSON and return value or original on failure. */
safeParseJson(): any;
/** Parse JSON and return value or null on failure. */
nullParseJson(): any | null;
/** Compare two paths by filename only. */
filenameCompare(otherPath: string): boolean;
/** Return substring between optional start and stop markers. */
substringFrom(startStr?: string, stopStr?: string): string;
/** Escape HTML special characters. */
escapeHTML(): string;
/** Unescape HTML entities to characters. */
unescapeHTML(): string;
/** Humanize identifiers: split camelCase, replace dashes/underscores, capitalize sentences. */
humanize(): string;
/** Convert to underscore_case. */
underscore(): string;
/** True if trimmed string is empty. */
isEmpty(): boolean;
/** Count occurrences of substring; case sensitive by default. */
countOccurrence(str2: string, caseSens?: boolean): number;
/** True if string represents a number. */
isNumber(): boolean;
/** True if string represents a float. */
isFloat(): boolean;
/** True if string is alphanumeric. */
isAlphaNumeric(): boolean;
/** True if string is all lowercase (with letters present). */
isLower(): boolean;
/** True if string is all uppercase (with letters present). */
isUpper(): boolean;
/** Simple non-crypto hash (hex); optional truncate. */
hashed(truncate?: number): string;
/** Replace the last occurrence of search with replacement. */
replaceLast(search: string | RegExp, replacement: string): string;
/** Remove diacritics (latinize). */
latinise(): string;
/** Truncate with "..." to total width. */
ellipsis(total: number): string;
/** Extract a numeric value from the string. */
toNumber(): number;
/** Parse boolean from common truthy/falsey words. */
toBoolean(): boolean;
/** Assert this is a non-empty string; returns NonEmpty or false. */
assertNonEmptyString(): (string & NonEmpty) | false;
/** True if string is non-empty after trimming (type guard). */
isNonEmty(): this is string & NonEmpty;
}
interface PrimeNumber {
/** Assert number is between `min` and `max` (type guard style). */
assertNrBetween(min?: number, max?: number): this is number;
/** True if integer. */
isInteger(): this is number;
/** True if finite (not NaN/Infinity). */
isFinite(): this is number;
/** True if safe integer. */
isSafeInteger(): this is number;
/** True if > 0. */
isPositive(): this is number;
/** True if < 0. */
isNegative(): this is number;
/** True if >= 0. */
isNonNegative(): this is number;
/** Assert integer (throws on failure). */
assertIsInteger(): asserts this is number;
/** Assert finite (throws on failure). */
assertIsFinite(): asserts this is number;
/** Like `toFixed` but returns a number. */
toFixedNumber(decimals?: number): number;
/** Check if number is between min and max (inclusive). */
between(min: number, max: number): boolean;
/** Clamp the number between min and max. */
clamp(min: number, max: number): number;
/** Run `fn` `n` times with index. */
times(fn: (i: number) => void): void;
/** Return string with leading zeros to reach `length`. */
toStringWithLeadingZeros(length: number): string;
/** Convert seconds/number to a timecode string. */
toTimeCode(): string;
/** Calculate what percent this number is of total. */
percentOf(total: number): number;
/** Calculate what ratio this number is of total. */
ratioOf(total: number): number;
}
interface PrimeArray<T> {
/** Return first element or first n elements. */
first(n?: number): T | T[];
/** Return last element or last n elements. */
last(n?: number): T | T[];
/** Find an item where `key` equals `value`. */
findByKey<K extends keyof T & string>(key: K, value: any): T | null;
/** Group items using a mapping function. */
groupBy(fn: (item: T) => string): Record<string, T[]>;
/** Group items by a property key. */
groupBy<K extends keyof T & string>(key: K): Record<string, T[]>;
/** Sum numeric values at the given key. */
sumByKey<K extends keyof T & string>(key: K): number;
/** Parse item string fields where applicable. */
autoParseKeys(): T[];
/** Return array with duplicates removed. */
unique(): T[];
/** Return a shuffled copy of the array. */
shuffle(): T[];
/** Return item with highest value for key or null. */
highestByKey<K extends keyof T & string>(key: K): T | null;
/** Return item with lowest value for key or null. */
lowestByKey<K extends keyof T & string>(key: K): T | null;
/** Sort array by key; ascending by default. */
sortByKey<K extends keyof T & string>(key: K, ascending?: boolean): T[];
/** Sort array by key name (string) with optional order. */
sortByKeyName<K extends keyof T & string>(key: K, ascending?: boolean): T[];
/** Map array to values of the given key. */
mapByKey<K extends keyof T & string>(key: K): Array<T[K]>;
/** Sum numeric values at key across objects. */
sumKey(key: string): number;
/** Average numeric values at key across objects. */
averageKey(key: string): number;
/** Filter by a key using predicate. */
filterKey(key: string, pred: (v: any) => boolean): T[];
/** Unique objects by key or projection function. */
distinct(keyOrFn: string | ((x: T) => any)): T[];
/** Group-reduce objects by key or projection. */
aggregate<R>(keyOrFn: string | ((x: T) => any), reducer: (acc: R, cur: T) => R, init: R): Record<string, R>;
/** Sum numeric values by key (string). */
sumBy(key: string): number;
/** Average numeric values by key (string). */
averageBy(key: string): number;
/** Sum all numeric values in the array. */
sum(): number;
/** Average all numeric values in the array. */
average(): number;
/** Return index of the highest number in the array. */
indexOfHighestNumber(): number;
/** Return index of the lowest number in the array. */
indexOfLowestNumber(): number;
/** Return intersection with another array (items present in both). */
intersect(other: T[]): T[];
/** Return difference with another array (items present only in this). */
difference(other: T[]): T[];
/** Validate each item; replace invalids with null and keep valid items. */
validateEach(validatorFn: (item: T) => boolean): (T | null)[];
/** Remove null and undefined values, returning a narrowed array. */
clearNil(): T[];
/** Group-reduce objects by key or projection. */
toTable(): Record<string, any[]>;
}
interface Pkit {
(value: undefined): null;
(value: null): boolean;
(value: string): PrimeString;
(value: number): PrimeNumber;
<T>(value: T[]): PrimeArray<T>;
(value: Record<string, any>): PrimeObject;
<T>(value: T): {
unwrap(): T;
};
math: MathUtils;
path: PathShim;
}
interface PrimeObject {
/** Type guard: is a plain object (not array). */
isObject(): this is Record<string, any>;
/** Assert object has provided keys. */
assertHasKeys<K extends string>(...keys: K[]): asserts this is Record<string, any> & Record<K, unknown>;
/** Cast after validation. */
asType<T>(): T;
/** True if all values are non-empty strings. */
isNonEmty(): this is Record<string, any> & Record<string, NonEmpty>;
/** Map: keys -> boolean flag if value is empty. */
mapEmptyToFalseyKeyObje(): Record<string, Boolean>;
/** Map: values -> boolean flag if value is empty. */
mapEmptyToFalseyValueArray(): Record<string, Boolean>;
/** Return a new object with keys sorted by `sorterFn`. */
sortKeys(sorterFn?: ((a: string, b: string) => number) | null): Record<string, any>;
/** Shallow structural equality by keys and types. */
equals(other: Record<string, any>): boolean;
/** Return object without specified keys. */
omit(...keys: string[]): Record<string, any>;
/** Return object containing only specified keys. */
pick(...keys: string[]): Record<string, any>;
/** Fill missing keys from source without overwriting existing. */
complement(src: Record<string, any>): Record<string, any>;
/** Remove empty string/null/undefined entries. */
clean(): Record<string, any>;
/** Ensure keys conform to schema; optional type coercion. */
ensureSchema(schema: Record<string, any>, opts?: {
coerce?: boolean;
}): Record<string, any>;
/** Filter object entries by predicate. */
filterEntries(predicate: (k: string, v: any) => boolean): Record<string, any>;
/** Merge with another object; control array merge strategy. */
merge(other: Record<string, any>, opts?: {
arrayStrategy?: "concat" | "replace" | "unique";
}): Record<string, any>;
/** Return a new object with keys sorted by `sorterFn`. */
sortKeys(sorterFn?: ((a: string, b: string) => number) | null): Record<string, any>;
/** Shallow structural equality by keys and types. */
equals(other: Record<string, any>): boolean;
/** Return object without specified keys. */
omit(...keys: string[]): Record<string, any>;
/** Return object containing only specified keys. */
pick(...keys: string[]): Record<string, any>;
/** Fill missing keys from source without overwriting existing. */
complement(src: Record<string, any>): Record<string, any>;
/** Remove empty string/null/undefined entries. */
clean(): Record<string, any>;
/** Ensure keys conform to schema; optional type coercion. */
ensureSchema(schema: Record<string, any>, opts?: {
coerce?: boolean;
}): Record<string, any>;
/** Filter object entries by predicate. */
filterEntries(predicate: (k: string, v: any) => boolean): Record<string, any>;
/** Merge with another object; control array merge strategy. */
merge(other: Record<string, any>, opts?: {
arrayStrategy?: "concat" | "replace" | "unique";
}): Record<string, any>;
}
declare const pkit: Pkit;
declare function applyPrimitives(): void;
export { type Pkit, type PrimeArray, type PrimeNumber, type PrimeObject, type PrimeString, applyPrimitives, applyPrimitives as applyPrimitivesGlobally, pkit };