Skip to content

Commit

Permalink
fixes support dot in property name #23
Browse files Browse the repository at this point in the history
  • Loading branch information
stefaanv authored and aleclarson committed Jul 19, 2024
1 parent a0e80d7 commit 6a0729e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
41 changes: 31 additions & 10 deletions src/object/crush.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, keys, objectify } from 'radashi'
import { isDate, isPrimitive, objectify } from "radashi";

/**
* Flattens a deep object to a single dimension, converting the keys
Expand All @@ -11,13 +11,34 @@ import { get, keys, objectify } from 'radashi'
* // { name: 'ra', 'children.0.name': 'hathor' }
* ```
*/
export function crush<TValue extends object>(value: TValue): object {
if (!value) {
return {}
}
return objectify(
keys(value),
k => k,
k => get(value, k),
)
type Primitive =
| number
| string
| boolean
| Date
| symbol
| bigint
| undefined
| null;

export function crush<TValue extends object>(
value: TValue,
): Record<string, Primitive> | Record<string, never> {
if (!value) return {};
const crushToPvArray: (
obj: object,
path: string,
) => Array<{ p: string; v: Primitive }> = (obj: object, path: string) =>
Object.entries(obj).flatMap(([key, value]) =>
isPrimitive(value) || isDate(value)
? { p: path === "" ? key : `${path}.${key}`, v: value }
: crushToPvArray(value, path === "" ? key : `${path}.${key}`),
);

const result = objectify(
crushToPvArray(value, ""),
(o) => o.p,
(o) => o.v,
);
return result;
}
26 changes: 25 additions & 1 deletion tests/object/crush.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,36 @@ describe('crush', () => {
timestamp: now,
})
})
test('handles property names with dots', () => {
test('handles property names with dots 1', () => {
const obj = {
a: { 'b.c': 'value' }
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value'
})
})
test('handles property names with dots 2', () => {
const obj = {
'a.b': { c: 'value' }
}
expect(_.crush(obj)).toEqual({
'a.b.c': 'value'
})
})
test('handles property names with dots 3', () => {
const obj = {
'a.b': { 'c.d': 123.4 }
}
expect(_.crush(obj)).toEqual({
'a.b.c.d': 123.4
})
})
test('handles arrays', () => {
const obj = ['value', 123.4, true]
expect(_.crush(obj)).toEqual({
'0': 'value',
'1': 123.4,
'2': true
})
})
})

0 comments on commit 6a0729e

Please sign in to comment.