export type PascalToCamel<S extends string> = S extends `${infer F}${infer R}` ? `${Lowercase<F>}${R}` : S

export const isRecordOrArray = (input: unknown): input is { [x: PropertyKey]: unknown } =>
    typeof input === "object" && input !== null
// biome-ignore lint/complexity/noBannedTypes: it's completely fine
export const isFunction = (input: unknown): input is Function => typeof input === "function"
export const isObject = (input: unknown): input is object => isRecordOrArray(input) || isFunction(input)
export const hasProperty = <P extends PropertyKey>(self: unknown, property: P): self is { [K in P]: unknown } =>
    isObject(self) && (property in self)

export const camelToSnake = (self: string): string => self.replace(/([A-Z])/g, "_$1").toLowerCase()
export const snakeToPascal = (self: string): string => {
    let str = self[0].toUpperCase()
    for (let i = 1; i < self.length; i++) {
        str += self[i] === "_" ? self[++i].toUpperCase() : self[i]
    }
    return str
}
