import { defaultExceptions } from "./defaultExceptions" export function toSnake(camel: Array, exceptions?: string[], recursionHistory?: string): Array export function toSnake( camel: Record, exceptions?: string[], recursionHistory?: string ): Record export function toSnake(camel: T, exceptions?: string[], recursionHistory?: string): T export function toSnake( camel: Record | Array | unknown, exceptions: string[] = defaultExceptions, recursionHistory?: string ): Record | Array | unknown { return Array.isArray(camel) ? camel.map(c => toSnake(c, exceptions, `${recursionHistory ? recursionHistory + "." : ""}[*]`)) : typeof camel == "object" && camel != null ? Object.entries(camel).reduce>((result, entry) => { const newHistory = `${recursionHistory ? recursionHistory + "." : ""}${entry[0]}` return exceptions.some(e => (e.startsWith("*.") ? newHistory.endsWith(e.substring(2)) : newHistory == e)) ? { ...result, [entry[0]]: entry[1] } : { ...result, [entry[0].length > 0 ? entry[0][0] + entry[0].substring(1, entry[0].length).replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`) : ""]: toSnake(entry[1], exceptions, newHistory), } }, {}) : camel }