/**
 * Converts a snake_case string to camelCase
 */
export const snakeToCamelString = (str: string): string =>
    str.replace(/([-_][a-z])/gi, ($1) =>
        $1.toUpperCase().replace('-', '').replace('_', '')
    );

/**
 * Recursively converts object keys from snake_case to camelCase
 */
export const snakeToCamel = (obj: any): any => {
    if (Array.isArray(obj)) {
        return obj.map((v) => snakeToCamel(v));
    } else if (obj !== null && typeof obj === 'object' && !(obj instanceof File)) {
        return Object.keys(obj).reduce(
            (result, key) => ({
                ...result,
                [snakeToCamelString(key)]: snakeToCamel(obj[key]),
            }),
            {}
        );
    }
    return obj;
};

/**
 * Converts a camelCase string to snake_case
 */
export const camelToSnakeString = (str: string): string =>
    str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);

/**
 * Recursively converts object keys from camelCase to snake_case
 */
export const camelToSnake = (obj: any): any => {
    if (Array.isArray(obj)) {
        return obj.map((v) => camelToSnake(v));
    } else if (obj !== null && typeof obj === 'object' && !(obj instanceof File)) {
        return Object.keys(obj).reduce(
            (result, key) => ({
                ...result,
                [camelToSnakeString(key)]: camelToSnake(obj[key]),
            }),
            {}
        );
    }
    return obj;
};
