2022-04-04 21:39:28 +00:00
|
|
|
import { snakeCase } from "case-anything";
|
|
|
|
|
|
|
|
// https://stackoverflow.com/questions/60269936/typescript-convert-generic-object-from-snake-to-camel-case
|
|
|
|
|
|
|
|
// Typescript magic to convert any string from camelCase to snake_case at compile time
|
|
|
|
type SnakeCase<S> =
|
2022-04-06 17:35:29 +00:00
|
|
|
S extends string ?
|
|
|
|
S extends `${infer T}${infer U}` ?
|
|
|
|
`${T extends Capitalize<T> ? "_" : ""}${Lowercase<T>}${SnakeCase<U>}` :
|
|
|
|
S :
|
|
|
|
S;
|
2022-04-04 21:39:28 +00:00
|
|
|
|
|
|
|
type SnakeCased<Type> = {
|
2022-04-06 17:35:29 +00:00
|
|
|
[Property in keyof Type as SnakeCase<Property>]: SnakeCased<Type[Property]>
|
2022-04-04 21:39:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default function snakeCaseTree<T>(object: T): SnakeCased<T> {
|
2022-04-06 17:35:29 +00:00
|
|
|
const snakeObject: any = {};
|
|
|
|
for (const key in object) {
|
2022-04-22 19:43:01 +00:00
|
|
|
snakeObject[snakeCase(key, { keepSpecialCharacters: true })] = snakeCaseValue(object[key]);
|
2022-04-06 17:35:29 +00:00
|
|
|
}
|
|
|
|
return snakeObject;
|
2022-04-04 21:39:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function snakeCaseValue(value: any): any {
|
2022-04-06 17:35:29 +00:00
|
|
|
if (typeof value === "object") {
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
return value.map(snakeCaseValue);
|
2022-04-04 21:39:28 +00:00
|
|
|
} else {
|
2022-04-06 17:35:29 +00:00
|
|
|
return snakeCaseTree(value);
|
2022-04-04 21:39:28 +00:00
|
|
|
}
|
2022-04-06 17:35:29 +00:00
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
2022-04-04 21:39:28 +00:00
|
|
|
}
|