Skip to content

Commit b571f57

Browse files
fix(util): CamelToSnake return nested primitives and add tests (#1229)
Co-authored-by: Sam Goodwin <[email protected]>
1 parent f236a51 commit b571f57

File tree

4 files changed

+443
-33
lines changed

4 files changed

+443
-33
lines changed

alchemy/src/util/camel-to-snake.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,41 @@ export interface LogPushProps {
22
maxFooBar: string;
33
}
44

5-
export function camelToSnakeObjectDeep<T extends object | undefined>(
5+
export function camelToSnakeObjectDeep<T>(
66
obj: T,
7-
): T extends undefined ? undefined : CamelToSnake<T> {
8-
return (
9-
obj
10-
? Object.fromEntries(
11-
Object.entries(obj).map(([key, value]) => [
12-
key
13-
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2") // Handle consecutive capitals: "FOOBar" -> "FOO_Bar"
14-
.replace(/([a-z])([A-Z])/g, "$1_$2") // Handle normal camelCase: "fooBar" -> "foo_Bar"
15-
.toLowerCase(),
16-
Array.isArray(value)
17-
? value.map((element) =>
18-
typeof element === "object" && element !== null
19-
? camelToSnakeObjectDeep(element)
20-
: element,
21-
)
22-
: typeof value === "object" && value !== null
23-
? camelToSnakeObjectDeep(value)
24-
: value,
25-
]),
26-
)
27-
: undefined
28-
) as T extends undefined ? undefined : CamelToSnake<T>;
7+
): T extends undefined ? undefined : T extends object ? CamelToSnake<T> : T {
8+
if (obj === undefined || obj === null) {
9+
return obj as any;
10+
}
11+
12+
// If it's not an object (primitive types), return as-is
13+
if (typeof obj !== "object") {
14+
return obj as any;
15+
}
16+
17+
if (obj instanceof RegExp) {
18+
return obj as any;
19+
}
20+
21+
// Handle arrays
22+
if (Array.isArray(obj)) {
23+
return obj.map(camelToSnakeObjectDeep) as any;
24+
}
25+
26+
// Handle objects
27+
return Object.fromEntries(
28+
Object.entries(obj).map(([key, value]) => [
29+
key
30+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2") // Handle consecutive capitals: "FOOBar" -> "FOO_Bar"
31+
.replace(/([a-z])([A-Z])/g, "$1_$2") // Handle normal camelCase: "fooBar" -> "foo_Bar"
32+
.toLowerCase(),
33+
Array.isArray(value)
34+
? value.map(camelToSnakeObjectDeep)
35+
: typeof value === "object" && value !== null
36+
? camelToSnakeObjectDeep(value)
37+
: value,
38+
]),
39+
) as any;
2940
}
3041

3142
// Helper to check if a character is uppercase

0 commit comments

Comments
 (0)