UNPKG

@lodestar/utils

Version:

Utilities required across multiple lodestar packages

103 lines (88 loc) 3.06 kB
import Case from "case"; export type KeyCase = | "snake" | "constant" | "camel" | "param" | "header" | "pascal" //Same as squish | "dot" | "notransform"; export function toExpectedCase( value: string, expectedCase: KeyCase = "camel", customCasingMap?: Record<string, string> ): string { if (expectedCase === "notransform") return value; if (customCasingMap?.[value]) return customCasingMap[value]; switch (expectedCase) { case "param": return Case.kebab(value); case "dot": return Case.lower(value, ".", true); default: return Case[expectedCase](value); } } function isObjectObject(val: unknown): val is object { return val != null && typeof val === "object" && Array.isArray(val) === false; } export function isPlainObject(o: unknown): o is object { if (isObjectObject(o) === false) return false; // If has modified constructor const ctor = (o as Record<string, unknown>).constructor; if (typeof ctor !== "function") return false; // If has modified prototype const prot = ctor.prototype; if (isObjectObject(prot) === false) return false; // If constructor does not have an Object-specific method if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) { return false; } // Most likely a plain Object return true; } export function isEmptyObject(value: unknown): boolean { return isObjectObject(value) && Object.keys(value).length === 0; } /** * Creates an object with the same keys as object and values generated by running each own enumerable * string keyed property of object thru iteratee. * * Inspired on lodash.mapValues, see https://lodash.com/docs/4.17.15#mapValues */ // biome-ignore lint/suspicious/noExplicitAny: We need to use `any` type here export function mapValues<T extends {[K: string]: any}, R>( obj: T, iteratee: (value: T[keyof T], key: keyof T) => R ): {[K in keyof T]: R} { const output = {} as {[K in keyof T]: R}; for (const [key, value] of Object.entries(obj)) { output[key as keyof T] = iteratee(value, key); } return output; } export function objectToExpectedCase<T extends Record<string, unknown> | Record<string, unknown>[] | unknown[]>( obj: T, expectedCase: "snake" | "constant" | "camel" | "param" | "header" | "pascal" | "dot" | "notransform" = "camel" ): T { if (Array.isArray(obj)) { const newArr: unknown[] = []; for (let i = 0; i < obj.length; i++) { newArr[i] = objectToExpectedCase(obj[i] as T, expectedCase); } return newArr as unknown as T; } if (Object(obj) === obj) { const newObj: Record<string, unknown> = {}; for (const name of Object.getOwnPropertyNames(obj)) { const newName = toExpectedCase(name, expectedCase); if (newName !== name && Object.prototype.hasOwnProperty.call(obj, newName)) { throw new Error(`object already has a ${newName} property`); } newObj[newName] = objectToExpectedCase(obj[name] as Record<string, unknown>, expectedCase); } return newObj as T; } return obj; }