@helpers4/object 2.0.0-alpha.9 → 2.0.0-beta.0

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/llms.txt ADDED
@@ -0,0 +1,577 @@
1
+ # @helpers4/object
2
+
3
+ > Tree-shakable TypeScript utility functions for the `object` domain.
4
+ > Package: `@helpers4/object` — Version: 2.0.0-beta.0
5
+ > License: LGPL-3.0-or-later
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @helpers4/object
11
+ # or
12
+ pnpm add @helpers4/object
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { compact, deepClone, deepCompare, ... } from '@helpers4/object';
19
+ ```
20
+
21
+ ## Functions
22
+
23
+ | Function | Description |
24
+ |---|---|
25
+ | `compact` | Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `""`, `NaN`) from an objec |
26
+ | `deepClone` | Creates a deep copy of an object or array |
27
+ | `deepCompare` | Deep comparison of two objects that returns detailed information about differences. |
28
+ | `deepMerge` | Merges two or more objects deeply |
29
+ | `get` | Gets a value from an object using a dot-notated path |
30
+ | `omit` | Creates a new object without the specified keys. |
31
+ | `pick` | Creates a new object with only the specified keys. |
32
+ | `removeUndefinedNull` | Remove null and undefined values from an object. |
33
+ | `safeJsonParse` | Parses a JSON string, returning `null` (or a fallback) on any parse failure. Unlike `JSON.parse`, t |
34
+ | `set` | Sets a value in an object using a dot-notated path |
35
+ | `shallowEquals` | Quick comparison of two objects using JSON.stringify. This is a fast but simple comparison that may |
36
+
37
+ ---
38
+
39
+ ## API Reference
40
+
41
+ ### `compact`
42
+
43
+ Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `""`, `NaN`) from an object.
44
+
45
+ ```typescript
46
+ import { compact } from '@helpers4/object';
47
+
48
+ compact<T extends Record<string, unknown>>(obj: T): Partial<T>
49
+ ```
50
+
51
+ **Parameters:**
52
+
53
+ - `obj: T` — The source object
54
+
55
+ **Returns:** `Partial<T>` — A new object containing only entries with truthy values
56
+
57
+ ```typescript
58
+ import { compact } from '@helpers4/object';
59
+
60
+ compact(obj: undefined): undefined
61
+ ```
62
+
63
+ **Parameters:**
64
+
65
+ - `obj: undefined` — The source object
66
+
67
+ **Returns:** `undefined` — A new object containing only entries with truthy values
68
+
69
+ ```typescript
70
+ import { compact } from '@helpers4/object';
71
+
72
+ compact(obj: null): null
73
+ ```
74
+
75
+ **Parameters:**
76
+
77
+ - `obj: null` — The source object
78
+
79
+ **Returns:** `null` — A new object containing only entries with truthy values
80
+
81
+ **Examples:**
82
+
83
+ *Remove falsy values from object*
84
+
85
+ Removes all entries with falsy values (false, null, undefined, 0, "", NaN).
86
+
87
+ ```typescript
88
+ compact({ a: 1, b: null, c: '', d: 0, e: 'hello' })
89
+ // => { a: 1, e: 'hello' }
90
+ ```
91
+
92
+ *Clean up API response*
93
+
94
+ Useful to strip empty or missing fields before sending data.
95
+
96
+ ```typescript
97
+ compact({ name: 'Alice', email: '', age: 0, role: 'admin' })
98
+ // => { name: 'Alice', role: 'admin' }
99
+ ```
100
+
101
+ ---
102
+
103
+ ### `deepClone`
104
+
105
+ Creates a deep copy of an object or array
106
+
107
+ ```typescript
108
+ import { deepClone } from '@helpers4/object';
109
+
110
+ deepClone<T>(obj: T): T
111
+ ```
112
+
113
+ **Parameters:**
114
+
115
+ - `obj: T` — The object to clone
116
+
117
+ **Returns:** `T` — Deep cloned object
118
+
119
+ **Examples:**
120
+
121
+ *Clone a nested object*
122
+
123
+ Creates a deep copy — modifying the clone does not affect the original.
124
+
125
+ ```typescript
126
+ const original = { a: { b: 1 } };
127
+ const cloned = deepClone(original);
128
+ cloned.a.b = 2;
129
+ // original.a.b is still 1
130
+ ```
131
+
132
+ ---
133
+
134
+ ### `deepCompare`
135
+
136
+ Deep comparison of two objects that returns detailed information about differences.
137
+
138
+ ```typescript
139
+ import { deepCompare } from '@helpers4/object';
140
+
141
+ deepCompare(objA: object | null | undefined, objB: object | null | undefined): boolean | DeepCompareResult
142
+ ```
143
+
144
+ **Parameters:**
145
+
146
+ - `objA: object | null | undefined` — First object to compare (can be object, undefined, or null)
147
+ - `objB: object | null | undefined` — Second object to compare (can be object, undefined, or null)
148
+
149
+ **Returns:** `boolean | DeepCompareResult` — `true` if objects are identical, `false` if incompatible types, or a `DeepCompareResult` object detailing differences
150
+
151
+ **Examples:**
152
+
153
+ *Compare nested objects*
154
+
155
+ Deeply compares two objects, returning true when they are structurally equal.
156
+
157
+ ```typescript
158
+ deepCompare({ a: { b: 1 } }, { a: { b: 1 } })
159
+ // => true
160
+ ```
161
+
162
+ *Detect deep differences*
163
+
164
+ Returns a detailed diff object when nested values differ.
165
+
166
+ ```typescript
167
+ deepCompare({ a: { b: 1 } }, { a: { b: 2 } })
168
+ // => { a: { b: false } }
169
+ ```
170
+
171
+ ---
172
+
173
+ ### `deepMerge`
174
+
175
+ Merges two or more objects deeply
176
+
177
+ ```typescript
178
+ import { deepMerge } from '@helpers4/object';
179
+
180
+ deepMerge<T extends Record<string, unknown>>(target: T, sources: Record<string, unknown>[]): T
181
+ ```
182
+
183
+ **Parameters:**
184
+
185
+ - `target: T` — The target object
186
+ - `sources: Record<string, unknown>[]` — The source objects to merge
187
+
188
+ **Returns:** `T` — The merged object
189
+
190
+ ```typescript
191
+ import { deepMerge } from '@helpers4/object';
192
+
193
+ deepMerge(target: undefined, sources: Record<string, unknown>[]): undefined
194
+ ```
195
+
196
+ **Parameters:**
197
+
198
+ - `target: undefined` — The target object
199
+ - `sources: Record<string, unknown>[]` — The source objects to merge
200
+
201
+ **Returns:** `undefined` — The merged object
202
+
203
+ ```typescript
204
+ import { deepMerge } from '@helpers4/object';
205
+
206
+ deepMerge(target: null, sources: Record<string, unknown>[]): null
207
+ ```
208
+
209
+ **Parameters:**
210
+
211
+ - `target: null` — The target object
212
+ - `sources: Record<string, unknown>[]` — The source objects to merge
213
+
214
+ **Returns:** `null` — The merged object
215
+
216
+ **Examples:**
217
+
218
+ *Merge two objects deeply*
219
+
220
+ Recursively merges source properties into the target object.
221
+
222
+ ```typescript
223
+ deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 })
224
+ // => { a: 1, b: { c: 2, d: 3 }, e: 4 }
225
+ ```
226
+
227
+ ---
228
+
229
+ ### `get`
230
+
231
+ Gets a value from an object using a dot-notated path
232
+
233
+ ```typescript
234
+ import { get } from '@helpers4/object';
235
+
236
+ get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined
237
+ ```
238
+
239
+ **Parameters:**
240
+
241
+ - `obj: unknown` — The object to get value from
242
+ - `path: string` — The dot-notated path (e.g., 'a.b.c')
243
+ - `defaultValue?: T` — Default value if path doesn't exist
244
+
245
+ **Returns:** `T | undefined` — The value at the path or default value
246
+
247
+ **Examples:**
248
+
249
+ *Access a nested property*
250
+
251
+ Uses a dot-notated path to retrieve a deeply nested value.
252
+
253
+ ```typescript
254
+ get({ a: { b: { c: 42 } } }, 'a.b.c')
255
+ // => 42
256
+ ```
257
+
258
+ *Return default for missing path*
259
+
260
+ Returns the default value when the path does not exist.
261
+
262
+ ```typescript
263
+ get({ a: 1 }, 'b.c', 'default')
264
+ // => 'default'
265
+ ```
266
+
267
+ ---
268
+
269
+ ### `omit`
270
+
271
+ Creates a new object without the specified keys.
272
+
273
+ ```typescript
274
+ import { omit } from '@helpers4/object';
275
+
276
+ omit<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Omit<T, K>
277
+ ```
278
+
279
+ **Parameters:**
280
+
281
+ - `obj: T` — The source object
282
+ - `keys: readonly K[]` — The keys to omit
283
+
284
+ **Returns:** `Omit<T, K>` — A new object without the omitted keys
285
+
286
+ ```typescript
287
+ import { omit } from '@helpers4/object';
288
+
289
+ omit(obj: undefined, keys: readonly string[]): undefined
290
+ ```
291
+
292
+ **Parameters:**
293
+
294
+ - `obj: undefined` — The source object
295
+ - `keys: readonly string[]` — The keys to omit
296
+
297
+ **Returns:** `undefined` — A new object without the omitted keys
298
+
299
+ ```typescript
300
+ import { omit } from '@helpers4/object';
301
+
302
+ omit(obj: null, keys: readonly string[]): null
303
+ ```
304
+
305
+ **Parameters:**
306
+
307
+ - `obj: null` — The source object
308
+ - `keys: readonly string[]` — The keys to omit
309
+
310
+ **Returns:** `null` — A new object without the omitted keys
311
+
312
+ **Examples:**
313
+
314
+ *Omit specific keys*
315
+
316
+ Creates a new object without the specified keys.
317
+
318
+ ```typescript
319
+ omit({ a: 1, b: 2, c: 3 }, ['b'])
320
+ // => { a: 1, c: 3 }
321
+ ```
322
+
323
+ *Remove sensitive fields*
324
+
325
+ Useful to strip sensitive data before sending to client.
326
+
327
+ ```typescript
328
+ const user = { id: 1, name: 'Alice', password: 'secret', token: 'abc123' };
329
+ omit(user, ['password', 'token'])
330
+ // => { id: 1, name: 'Alice' }
331
+ ```
332
+
333
+ ---
334
+
335
+ ### `pick`
336
+
337
+ Creates a new object with only the specified keys.
338
+
339
+ ```typescript
340
+ import { pick } from '@helpers4/object';
341
+
342
+ pick<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Pick<T, K>
343
+ ```
344
+
345
+ **Parameters:**
346
+
347
+ - `obj: T` — The source object
348
+ - `keys: readonly K[]` — The keys to pick
349
+
350
+ **Returns:** `Pick<T, K>` — A new object with only the picked keys
351
+
352
+ ```typescript
353
+ import { pick } from '@helpers4/object';
354
+
355
+ pick(obj: undefined, keys: readonly string[]): undefined
356
+ ```
357
+
358
+ **Parameters:**
359
+
360
+ - `obj: undefined` — The source object
361
+ - `keys: readonly string[]` — The keys to pick
362
+
363
+ **Returns:** `undefined` — A new object with only the picked keys
364
+
365
+ ```typescript
366
+ import { pick } from '@helpers4/object';
367
+
368
+ pick(obj: null, keys: readonly string[]): null
369
+ ```
370
+
371
+ **Parameters:**
372
+
373
+ - `obj: null` — The source object
374
+ - `keys: readonly string[]` — The keys to pick
375
+
376
+ **Returns:** `null` — A new object with only the picked keys
377
+
378
+ **Examples:**
379
+
380
+ *Pick specific keys*
381
+
382
+ Creates a new object with only the specified keys.
383
+
384
+ ```typescript
385
+ pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])
386
+ // => { a: 1, c: 3 }
387
+ ```
388
+
389
+ *Extract user fields*
390
+
391
+ Useful to select only the fields you need from an object.
392
+
393
+ ```typescript
394
+ const user = { id: 1, name: 'Alice', email: 'alice@example.com', password: 'secret' };
395
+ pick(user, ['id', 'name', 'email'])
396
+ // => { id: 1, name: 'Alice', email: 'alice@example.com' }
397
+ ```
398
+
399
+ ---
400
+
401
+ ### `removeUndefinedNull`
402
+
403
+ Remove null and undefined values from an object.
404
+
405
+ ```typescript
406
+ import { removeUndefinedNull } from '@helpers4/object';
407
+
408
+ removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T): Partial<T>
409
+ ```
410
+
411
+ **Parameters:**
412
+
413
+ - `obj: T` — an object
414
+
415
+ **Returns:** `Partial<T>` — A shallow copy of the object without null or undefined values
416
+
417
+ ```typescript
418
+ import { removeUndefinedNull } from '@helpers4/object';
419
+
420
+ removeUndefinedNull(obj: null): null
421
+ ```
422
+
423
+ **Parameters:**
424
+
425
+ - `obj: null` — a null object
426
+
427
+ **Returns:** `null` — null
428
+
429
+ ```typescript
430
+ import { removeUndefinedNull } from '@helpers4/object';
431
+
432
+ removeUndefinedNull(obj: undefined): undefined
433
+ ```
434
+
435
+ **Parameters:**
436
+
437
+ - `obj: undefined` — an undefined object
438
+
439
+ **Returns:** `undefined` — undefined
440
+
441
+ **Examples:**
442
+
443
+ *Strip null and undefined values*
444
+
445
+ Returns a shallow copy of the object without null or undefined properties.
446
+
447
+ ```typescript
448
+ removeUndefinedNull({ a: 1, b: null, c: undefined, d: 'ok' })
449
+ // => { a: 1, d: 'ok' }
450
+ ```
451
+
452
+ ---
453
+
454
+ ### `safeJsonParse`
455
+
456
+ Parses a JSON string, returning `null` (or a fallback) on any parse failure.
457
+
458
+ Unlike `JSON.parse`, this never throws. Invalid JSON strings and other
459
+ parsing edge-cases resolve to `null` or the provided `fallback`.
460
+
461
+ ```typescript
462
+ import { safeJsonParse } from '@helpers4/object';
463
+
464
+ safeJsonParse<T>(input: string): T | null
465
+ ```
466
+
467
+ **Parameters:**
468
+
469
+ - `input: string` — The JSON string to parse.
470
+
471
+ **Returns:** `T | null` — The parsed value typed as `T`, or `fallback` on failure.
472
+
473
+ ```typescript
474
+ import { safeJsonParse } from '@helpers4/object';
475
+
476
+ safeJsonParse<T>(input: string, fallback: T): T
477
+ ```
478
+
479
+ **Parameters:**
480
+
481
+ - `input: string` — The JSON string to parse.
482
+ - `fallback: T` — Value returned on failure. Defaults to `null` when omitted.
483
+
484
+ **Returns:** `T` — The parsed value typed as `T`, or `fallback` on failure.
485
+
486
+ **Examples:**
487
+
488
+ *Parse valid JSON*
489
+
490
+ Returns the parsed value when the input is valid JSON.
491
+
492
+ ```typescript
493
+ safeJsonParse<{ a: number }>('{"a":1}')
494
+ // => { a: 1 }
495
+ ```
496
+
497
+ *Return null on invalid input*
498
+
499
+ Returns null instead of throwing when JSON is malformed.
500
+
501
+ ```typescript
502
+ safeJsonParse('invalid')
503
+ // => null
504
+ ```
505
+
506
+ *Use a fallback value*
507
+
508
+ Returns the provided fallback when parsing fails.
509
+
510
+ ```typescript
511
+ safeJsonParse('invalid', [])
512
+ // => []
513
+ ```
514
+
515
+ ---
516
+
517
+ ### `set`
518
+
519
+ Sets a value in an object using a dot-notated path
520
+
521
+ ```typescript
522
+ import { set } from '@helpers4/object';
523
+
524
+ set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>
525
+ ```
526
+
527
+ **Parameters:**
528
+
529
+ - `obj: Record<string, unknown>` — The object to set value in
530
+ - `path: string` — The dot-notated path (e.g., 'a.b.c')
531
+ - `value: unknown` — The value to set
532
+
533
+ **Returns:** `Record<string, unknown>` — The modified object
534
+
535
+ **Examples:**
536
+
537
+ *Set a nested property*
538
+
539
+ Creates intermediate objects as needed along the dot-notated path.
540
+
541
+ ```typescript
542
+ set({}, 'a.b.c', 42)
543
+ // => { a: { b: { c: 42 } } }
544
+ ```
545
+
546
+ ---
547
+
548
+ ### `shallowEquals`
549
+
550
+ Quick comparison of two objects using JSON.stringify.
551
+ This is a fast but simple comparison that may not work for all edge cases.
552
+
553
+ ```typescript
554
+ import { shallowEquals } from '@helpers4/object';
555
+
556
+ shallowEquals(objA: unknown, objB: unknown): boolean
557
+ ```
558
+
559
+ **Parameters:**
560
+
561
+ - `objA: unknown` — First object to compare
562
+ - `objB: unknown` — Second object to compare
563
+
564
+ **Returns:** `boolean` — `true` if objects are identical according to JSON.stringify, `false` otherwise
565
+
566
+ **Examples:**
567
+
568
+ *Compare two equal objects*
569
+
570
+ Uses JSON.stringify for a fast comparison.
571
+
572
+ ```typescript
573
+ shallowEquals({ a: 1, b: 2 }, { a: 1, b: 2 })
574
+ // => true
575
+ ```
576
+
577
+ ---