@helpers4/object 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/lib/index.d.ts +174 -1
- package/lib/index.js +304 -35
- package/lib/index.js.map +1 -1
- package/llms.txt +293 -2
- package/meta/api.json +287 -1
- package/meta/examples.json +85 -0
- package/package.json +8 -1
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @helpers4/object
|
|
2
2
|
|
|
3
3
|
> Tree-shakable TypeScript utility functions for the `object` domain.
|
|
4
|
-
> Package: `@helpers4/object` — Version: 3.0.
|
|
4
|
+
> Package: `@helpers4/object` — Version: 3.0.3
|
|
5
5
|
> License: LGPL-3.0-or-later
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
@@ -15,13 +15,14 @@ pnpm add @helpers4/object
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import { clone, cloneDeep,
|
|
18
|
+
import { camelCaseKeys, clone, cloneDeep, ... } from '@helpers4/object';
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Functions
|
|
22
22
|
|
|
23
23
|
| Function | Description |
|
|
24
24
|
|---|---|
|
|
25
|
+
| `camelCaseKeys` | Recursively transforms every key of a plain object (including keys nested inside arrays and nested o |
|
|
25
26
|
| `clone` | Creates a shallow copy of a value — one level deep, unlike cloneDeep. Unlike a plain `{ ...value }` |
|
|
26
27
|
| `cloneDeep` | Creates a deep copy of an object or array. Recursively clones own enumerable string keys. `Date` in |
|
|
27
28
|
| `compact` | Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `""`, `NaN`) from an objec |
|
|
@@ -34,16 +35,22 @@ import { clone, cloneDeep, compact, ... } from '@helpers4/object';
|
|
|
34
35
|
| `invert` | Returns a new object with keys and values swapped. If multiple keys share the same value, the last o |
|
|
35
36
|
| `isEmpty` | Checks if a plain object has no own enumerable string-keyed properties. `null` and `undefined` are t |
|
|
36
37
|
| `isNonEmpty` | Checks if a plain object has at least one own enumerable string-keyed property. `null` and `undefine |
|
|
38
|
+
| `kebabCaseKeys` | Recursively transforms every key of a plain object (including keys nested inside arrays and nested o |
|
|
37
39
|
| `map` | Transforms the values and/or keys of a plain object in a single pass. Both callbacks are optional a |
|
|
40
|
+
| `mapDeep` | Recursively transforms the keys and/or values of a plain object — the deep counterpart to map, which |
|
|
38
41
|
| `mergeDeep` | Merges two or more objects deeply, returning a **new** object without mutating any input. Sources a |
|
|
39
42
|
| `omit` | Creates a new object without the specified keys. |
|
|
40
43
|
| `omitBy` | Creates a new object without the own enumerable entries for which `predicate` returns `true`. Compl |
|
|
41
44
|
| `parsePropertyPath` | Parses a dot/bracket-notation property path into an array of string/number key segments — the same n |
|
|
45
|
+
| `pascalCaseKeys` | Recursively transforms every key of a plain object (including keys nested inside arrays and nested o |
|
|
42
46
|
| `pick` | Creates a new object with only the specified keys. Keys that are prototype-polluting strings (`__pro |
|
|
43
47
|
| `pickBy` | Creates a new object with only the own enumerable entries for which `predicate` returns `true`. Com |
|
|
44
48
|
| `removeUndefinedNull` | Remove null and undefined values from an object. |
|
|
45
49
|
| `safeJsonParse` | Parses a JSON string, returning `null` (or a fallback) on any parse failure. Unlike `JSON.parse`, t |
|
|
46
50
|
| `set` | Sets a value in an object at the given path, creating intermediate objects as needed. **Two path fo |
|
|
51
|
+
| `snakeCaseKeys` | Recursively transforms every key of a plain object (including keys nested inside arrays and nested o |
|
|
52
|
+
| `sortKeys` | Creates a new object with the same entries as the input, but with its own keys sorted. Shallow only |
|
|
53
|
+
| `titleCaseKeys` | Recursively transforms every key of a plain object (including keys nested inside arrays and nested o |
|
|
47
54
|
| `unflatten` | Rebuilds a nested object from a single-level object whose keys are dot-notation paths. The inverse o |
|
|
48
55
|
| `unset` | Removes the value at a dot/bracket-notation path or explicit key array, mutating the object in place |
|
|
49
56
|
| `update` | Updates the value at a path by applying a function to its current value, creating intermediate objec |
|
|
@@ -52,6 +59,49 @@ import { clone, cloneDeep, compact, ... } from '@helpers4/object';
|
|
|
52
59
|
|
|
53
60
|
## API Reference
|
|
54
61
|
|
|
62
|
+
### `camelCaseKeys`
|
|
63
|
+
|
|
64
|
+
Recursively transforms every key of a plain object (including keys nested inside arrays and
|
|
65
|
+
nested objects) to camelCase. Handles snake_case, kebab-case, PascalCase, and space-separated
|
|
66
|
+
keys. Non-plain-object values (arrays' items aside) — `Date`, `Map`, `Set`, class instances,
|
|
67
|
+
primitives — are left untouched, only their position is walked into. An entry whose
|
|
68
|
+
transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is
|
|
69
|
+
silently skipped, same as the rest of `@helpers4/object`.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { camelCaseKeys } from '@helpers4/object';
|
|
73
|
+
|
|
74
|
+
camelCaseKeys<T>(value: T): T
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Parameters:**
|
|
78
|
+
|
|
79
|
+
- `value: T` — The object (or array of objects) to transform
|
|
80
|
+
|
|
81
|
+
**Returns:** `T` — A new value with every plain-object key converted to camelCase
|
|
82
|
+
|
|
83
|
+
**Examples:**
|
|
84
|
+
|
|
85
|
+
*Convert a snake_case API response*
|
|
86
|
+
|
|
87
|
+
Recursively converts every key, including nested objects, to camelCase.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
camelCaseKeys({ user_name: 'Alice', home_address: { zip_code: '12345' } })
|
|
91
|
+
// => { userName: 'Alice', homeAddress: { zipCode: '12345' } }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
*Arrays of objects are walked too*
|
|
95
|
+
|
|
96
|
+
Each object inside an array gets its keys converted.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
camelCaseKeys({ user_list: [{ first_name: 'A' }] })
|
|
100
|
+
// => { userList: [{ firstName: 'A' }] }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
55
105
|
### `clone`
|
|
56
106
|
|
|
57
107
|
Creates a shallow copy of a value — one level deep, unlike cloneDeep.
|
|
@@ -675,6 +725,40 @@ function processConfig(config: Record<string, unknown>): void {
|
|
|
675
725
|
|
|
676
726
|
---
|
|
677
727
|
|
|
728
|
+
### `kebabCaseKeys`
|
|
729
|
+
|
|
730
|
+
Recursively transforms every key of a plain object (including keys nested inside arrays and
|
|
731
|
+
nested objects) to kebab-case. Handles snake_case, camelCase, PascalCase, and space-separated
|
|
732
|
+
keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left
|
|
733
|
+
untouched, only their position is walked into. An entry whose transformed key is a
|
|
734
|
+
prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped,
|
|
735
|
+
same as the rest of `@helpers4/object`.
|
|
736
|
+
|
|
737
|
+
```typescript
|
|
738
|
+
import { kebabCaseKeys } from '@helpers4/object';
|
|
739
|
+
|
|
740
|
+
kebabCaseKeys<T>(value: T): T
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
**Parameters:**
|
|
744
|
+
|
|
745
|
+
- `value: T` — The object (or array of objects) to transform
|
|
746
|
+
|
|
747
|
+
**Returns:** `T` — A new value with every plain-object key converted to kebab-case
|
|
748
|
+
|
|
749
|
+
**Examples:**
|
|
750
|
+
|
|
751
|
+
*Convert object keys for a kebab-case config format*
|
|
752
|
+
|
|
753
|
+
Recursively converts every key, including nested objects, to kebab-case.
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
kebabCaseKeys({ userName: 'Alice', homeAddress: { zipCode: '12345' } })
|
|
757
|
+
// => { 'user-name': 'Alice', 'home-address': { 'zip-code': '12345' } }
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
678
762
|
### `map`
|
|
679
763
|
|
|
680
764
|
Transforms the values and/or keys of a plain object in a single pass.
|
|
@@ -738,6 +822,70 @@ map(
|
|
|
738
822
|
|
|
739
823
|
---
|
|
740
824
|
|
|
825
|
+
### `mapDeep`
|
|
826
|
+
|
|
827
|
+
Recursively transforms the keys and/or values of a plain object — the deep counterpart to
|
|
828
|
+
map, which only transforms the top level. Descends into nested plain objects and
|
|
829
|
+
arrays of them; `Date`, `Map`, `Set`, class instances, and primitives are left untouched
|
|
830
|
+
(only their position is walked into, matching cloneDeep's notion of what counts
|
|
831
|
+
as a plain-data node worth recursing into).
|
|
832
|
+
|
|
833
|
+
Both callbacks are optional and default to identity (no transformation). `mapKey` is called
|
|
834
|
+
with the *original* key and value (before any recursive value transform); `mapValue` receives
|
|
835
|
+
the already-recursed value. Entries whose mapped key is a prototype-polluting string
|
|
836
|
+
(`__proto__`, `constructor`, `prototype`) are silently skipped, same as map.
|
|
837
|
+
|
|
838
|
+
Array elements also go through `mapValue` (with their stringified index as `key`, since
|
|
839
|
+
arrays have no property keys of their own) — so values inside a plain array, not just object
|
|
840
|
+
properties, get transformed too. `mapKey` is never called for array elements, since there is
|
|
841
|
+
no key to rename.
|
|
842
|
+
|
|
843
|
+
```typescript
|
|
844
|
+
import { mapDeep } from '@helpers4/object';
|
|
845
|
+
|
|
846
|
+
mapDeep<T>(obj: T, mapValue?: function, mapKey?: function): T
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Parameters:**
|
|
850
|
+
|
|
851
|
+
- `obj: T` — The value to transform (typically an object, or an array of objects)
|
|
852
|
+
- `mapValue?: function` — Callback called with `(value, key)` for each entry's (already-recursed) value.
|
|
853
|
+
For array elements, `key` is the element's index as a string. Defaults to identity.
|
|
854
|
+
- `mapKey?: function` — Callback called with `(key, value)` for each object entry. Defaults to identity.
|
|
855
|
+
|
|
856
|
+
**Returns:** `T` — A new value with every plain-object key/value transformed
|
|
857
|
+
|
|
858
|
+
**Examples:**
|
|
859
|
+
|
|
860
|
+
*Transform every key, recursively*
|
|
861
|
+
|
|
862
|
+
Unlike map(), mapDeep() walks into nested objects and arrays of objects.
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
mapDeep({ a: { b: 1 } }, undefined, key => key.toUpperCase())
|
|
866
|
+
// => { A: { B: 1 } }
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
*Transform every value, recursively*
|
|
870
|
+
|
|
871
|
+
Values are visited after their own nested content has already been transformed.
|
|
872
|
+
|
|
873
|
+
```typescript
|
|
874
|
+
mapDeep({ a: { b: 1, c: 2 } }, v => typeof v === 'number' ? v * 10 : v)
|
|
875
|
+
// => { a: { b: 10, c: 20 } }
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
*Transform values inside arrays too*
|
|
879
|
+
|
|
880
|
+
Array elements are visited by mapValue as well, keyed by their stringified index.
|
|
881
|
+
|
|
882
|
+
```typescript
|
|
883
|
+
mapDeep({ tags: [1, 2, 3] }, v => typeof v === 'number' ? v * 10 : v)
|
|
884
|
+
// => { tags: [10, 20, 30] }
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
---
|
|
888
|
+
|
|
741
889
|
### `mergeDeep`
|
|
742
890
|
|
|
743
891
|
Merges two or more objects deeply, returning a **new** object without mutating any input.
|
|
@@ -957,6 +1105,40 @@ parsePropertyPath('a[0]b')
|
|
|
957
1105
|
|
|
958
1106
|
---
|
|
959
1107
|
|
|
1108
|
+
### `pascalCaseKeys`
|
|
1109
|
+
|
|
1110
|
+
Recursively transforms every key of a plain object (including keys nested inside arrays and
|
|
1111
|
+
nested objects) to PascalCase. Handles camelCase, snake_case, kebab-case, and space-separated
|
|
1112
|
+
keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left
|
|
1113
|
+
untouched, only their position is walked into. An entry whose transformed key is a
|
|
1114
|
+
prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped,
|
|
1115
|
+
same as the rest of `@helpers4/object`.
|
|
1116
|
+
|
|
1117
|
+
```typescript
|
|
1118
|
+
import { pascalCaseKeys } from '@helpers4/object';
|
|
1119
|
+
|
|
1120
|
+
pascalCaseKeys<T>(value: T): T
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
**Parameters:**
|
|
1124
|
+
|
|
1125
|
+
- `value: T` — The object (or array of objects) to transform
|
|
1126
|
+
|
|
1127
|
+
**Returns:** `T` — A new value with every plain-object key converted to PascalCase
|
|
1128
|
+
|
|
1129
|
+
**Examples:**
|
|
1130
|
+
|
|
1131
|
+
*Convert object keys to PascalCase (e.g. for a C#/JSON.NET consumer)*
|
|
1132
|
+
|
|
1133
|
+
Recursively converts every key, including nested objects, to PascalCase.
|
|
1134
|
+
|
|
1135
|
+
```typescript
|
|
1136
|
+
pascalCaseKeys({ user_name: 'Alice', home_address: { zip_code: '12345' } })
|
|
1137
|
+
// => { UserName: 'Alice', HomeAddress: { ZipCode: '12345' } }
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
---
|
|
1141
|
+
|
|
960
1142
|
### `pick`
|
|
961
1143
|
|
|
962
1144
|
Creates a new object with only the specified keys.
|
|
@@ -1256,6 +1438,115 @@ set({}, ['user', id], 'alice')
|
|
|
1256
1438
|
|
|
1257
1439
|
---
|
|
1258
1440
|
|
|
1441
|
+
### `snakeCaseKeys`
|
|
1442
|
+
|
|
1443
|
+
Recursively transforms every key of a plain object (including keys nested inside arrays and
|
|
1444
|
+
nested objects) to snake_case. Handles camelCase, PascalCase, kebab-case, and space-separated
|
|
1445
|
+
keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left
|
|
1446
|
+
untouched, only their position is walked into. An entry whose transformed key is a
|
|
1447
|
+
prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped,
|
|
1448
|
+
same as the rest of `@helpers4/object`.
|
|
1449
|
+
|
|
1450
|
+
```typescript
|
|
1451
|
+
import { snakeCaseKeys } from '@helpers4/object';
|
|
1452
|
+
|
|
1453
|
+
snakeCaseKeys<T>(value: T): T
|
|
1454
|
+
```
|
|
1455
|
+
|
|
1456
|
+
**Parameters:**
|
|
1457
|
+
|
|
1458
|
+
- `value: T` — The object (or array of objects) to transform
|
|
1459
|
+
|
|
1460
|
+
**Returns:** `T` — A new value with every plain-object key converted to snake_case
|
|
1461
|
+
|
|
1462
|
+
**Examples:**
|
|
1463
|
+
|
|
1464
|
+
*Convert a camelCase object for a snake_case API*
|
|
1465
|
+
|
|
1466
|
+
Recursively converts every key, including nested objects, to snake_case.
|
|
1467
|
+
|
|
1468
|
+
```typescript
|
|
1469
|
+
snakeCaseKeys({ userName: 'Alice', homeAddress: { zipCode: '12345' } })
|
|
1470
|
+
// => { user_name: 'Alice', home_address: { zip_code: '12345' } }
|
|
1471
|
+
```
|
|
1472
|
+
|
|
1473
|
+
---
|
|
1474
|
+
|
|
1475
|
+
### `sortKeys`
|
|
1476
|
+
|
|
1477
|
+
Creates a new object with the same entries as the input, but with its own keys sorted.
|
|
1478
|
+
Shallow only — nested objects are copied as-is, their keys are not re-sorted.
|
|
1479
|
+
Key order matters for things like `JSON.stringify` diffs and snapshot stability; this does
|
|
1480
|
+
not change equality (`{a:1,b:2}` and `{b:2,a:1}` are already equal), just iteration/serialization order.
|
|
1481
|
+
Note: integer-index-like keys (`"0"`, `"1"`, `"42"`...) are always iterated first, in numeric
|
|
1482
|
+
order, by the JS engine itself — no object key ordering can override that language behavior.
|
|
1483
|
+
A prototype-polluting key (`__proto__`, `constructor`, `prototype`) is silently skipped,
|
|
1484
|
+
same as the rest of `@helpers4/object`.
|
|
1485
|
+
|
|
1486
|
+
```typescript
|
|
1487
|
+
import { sortKeys } from '@helpers4/object';
|
|
1488
|
+
|
|
1489
|
+
sortKeys<T extends Record<string, unknown>>(obj: T, compareFn?: function): T
|
|
1490
|
+
```
|
|
1491
|
+
|
|
1492
|
+
**Parameters:**
|
|
1493
|
+
|
|
1494
|
+
- `obj: T` — The object whose keys to sort
|
|
1495
|
+
- `compareFn?: function` — Optional custom comparator, passed directly to `Array.prototype.sort`
|
|
1496
|
+
|
|
1497
|
+
**Returns:** `T` — A new object with the same entries, own keys in sorted order
|
|
1498
|
+
|
|
1499
|
+
**Examples:**
|
|
1500
|
+
|
|
1501
|
+
*Sort object keys alphabetically*
|
|
1502
|
+
|
|
1503
|
+
Useful for stable JSON.stringify output or predictable snapshot tests.
|
|
1504
|
+
|
|
1505
|
+
```typescript
|
|
1506
|
+
sortKeys({ b: 2, a: 1, c: 3 })
|
|
1507
|
+
// => { a: 1, b: 2, c: 3 }
|
|
1508
|
+
```
|
|
1509
|
+
|
|
1510
|
+
---
|
|
1511
|
+
|
|
1512
|
+
### `titleCaseKeys`
|
|
1513
|
+
|
|
1514
|
+
Recursively transforms every key of a plain object (including keys nested inside arrays and
|
|
1515
|
+
nested objects) to Title Case. Handles camelCase, snake_case, kebab-case, and space-separated
|
|
1516
|
+
keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left
|
|
1517
|
+
untouched, only their position is walked into. An entry whose transformed key is a
|
|
1518
|
+
prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped,
|
|
1519
|
+
same as the rest of `@helpers4/object`.
|
|
1520
|
+
|
|
1521
|
+
Note: unlike the other `*CaseKeys` variants, `titleCase` joins words with spaces (e.g.
|
|
1522
|
+
`'User Name'`) — those keys are only usable via bracket access (`obj['User Name']`), not dot
|
|
1523
|
+
notation. Useful for display-facing structures (form labels, table headers), not wire formats.
|
|
1524
|
+
|
|
1525
|
+
```typescript
|
|
1526
|
+
import { titleCaseKeys } from '@helpers4/object';
|
|
1527
|
+
|
|
1528
|
+
titleCaseKeys<T>(value: T): T
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
**Parameters:**
|
|
1532
|
+
|
|
1533
|
+
- `value: T` — The object (or array of objects) to transform
|
|
1534
|
+
|
|
1535
|
+
**Returns:** `T` — A new value with every plain-object key converted to Title Case
|
|
1536
|
+
|
|
1537
|
+
**Examples:**
|
|
1538
|
+
|
|
1539
|
+
*Convert object keys into display-friendly labels*
|
|
1540
|
+
|
|
1541
|
+
Recursively converts every key to Title Case — useful for form labels or table headers.
|
|
1542
|
+
|
|
1543
|
+
```typescript
|
|
1544
|
+
titleCaseKeys({ user_name: 'Alice', home_address: { zip_code: '12345' } })
|
|
1545
|
+
// => { 'User Name': 'Alice', 'Home Address': { 'Zip Code': '12345' } }
|
|
1546
|
+
```
|
|
1547
|
+
|
|
1548
|
+
---
|
|
1549
|
+
|
|
1259
1550
|
### `unflatten`
|
|
1260
1551
|
|
|
1261
1552
|
Rebuilds a nested object from a single-level object whose keys are
|