@helpers4/object 2.0.0-alpha.9 → 2.0.0-beta.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/meta/api.json CHANGED
@@ -1,7 +1,79 @@
1
1
  {
2
2
  "category": "object",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.3",
4
4
  "functions": [
5
+ {
6
+ "name": "compact",
7
+ "kind": "function",
8
+ "description": "Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.",
9
+ "since": "2.0.0",
10
+ "signatures": [
11
+ {
12
+ "signature": "compact<T extends Record<string, unknown>>(obj: T): Partial<T>",
13
+ "description": "Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.",
14
+ "params": [
15
+ {
16
+ "name": "obj",
17
+ "type": "T",
18
+ "description": "The source object"
19
+ }
20
+ ],
21
+ "returns": {
22
+ "type": "Partial<T>",
23
+ "description": "A new object containing only entries with truthy values"
24
+ },
25
+ "typeParameters": [
26
+ {
27
+ "name": "T",
28
+ "constraint": "Record<string, unknown>"
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "signature": "compact(obj: undefined): undefined",
34
+ "description": "Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.",
35
+ "params": [
36
+ {
37
+ "name": "obj",
38
+ "type": "undefined",
39
+ "description": "The source object"
40
+ }
41
+ ],
42
+ "returns": {
43
+ "type": "undefined",
44
+ "description": "A new object containing only entries with truthy values"
45
+ }
46
+ },
47
+ {
48
+ "signature": "compact(obj: null): null",
49
+ "description": "Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.",
50
+ "params": [
51
+ {
52
+ "name": "obj",
53
+ "type": "null",
54
+ "description": "The source object"
55
+ }
56
+ ],
57
+ "returns": {
58
+ "type": "null",
59
+ "description": "A new object containing only entries with truthy values"
60
+ }
61
+ }
62
+ ],
63
+ "examples": [
64
+ {
65
+ "title": "Remove falsy values from object",
66
+ "description": "Removes all entries with falsy values (false, null, undefined, 0, \"\", NaN).",
67
+ "code": "compact({ a: 1, b: null, c: '', d: 0, e: 'hello' })\n// => { a: 1, e: 'hello' }"
68
+ },
69
+ {
70
+ "title": "Clean up API response",
71
+ "description": "Useful to strip empty or missing fields before sending data.",
72
+ "code": "compact({ name: 'Alice', email: '', age: 0, role: 'admin' })\n// => { name: 'Alice', role: 'admin' }"
73
+ }
74
+ ],
75
+ "sourceFile": "compact.ts"
76
+ },
5
77
  {
6
78
  "name": "deepClone",
7
79
  "kind": "function",
@@ -39,29 +111,117 @@
39
111
  "sourceFile": "deepClone.ts"
40
112
  },
41
113
  {
42
- "name": "deepCompare",
114
+ "name": "deepMerge",
43
115
  "kind": "function",
44
- "description": "Deep comparison of two objects that returns detailed information about differences.",
116
+ "description": "Merges two or more objects deeply",
117
+ "since": "1.9.0",
118
+ "signatures": [
119
+ {
120
+ "signature": "deepMerge<T extends Record<string, unknown>>(target: T, sources: Record<string, unknown>[]): T",
121
+ "description": "Merges two or more objects deeply",
122
+ "params": [
123
+ {
124
+ "name": "target",
125
+ "type": "T",
126
+ "description": "The target object"
127
+ },
128
+ {
129
+ "name": "sources",
130
+ "type": "Record<string, unknown>[]",
131
+ "description": "The source objects to merge"
132
+ }
133
+ ],
134
+ "returns": {
135
+ "type": "T",
136
+ "description": "The merged object"
137
+ },
138
+ "typeParameters": [
139
+ {
140
+ "name": "T",
141
+ "constraint": "Record<string, unknown>"
142
+ }
143
+ ]
144
+ },
145
+ {
146
+ "signature": "deepMerge(target: undefined, sources: Record<string, unknown>[]): undefined",
147
+ "description": "Merges two or more objects deeply",
148
+ "params": [
149
+ {
150
+ "name": "target",
151
+ "type": "undefined",
152
+ "description": "The target object"
153
+ },
154
+ {
155
+ "name": "sources",
156
+ "type": "Record<string, unknown>[]",
157
+ "description": "The source objects to merge"
158
+ }
159
+ ],
160
+ "returns": {
161
+ "type": "undefined",
162
+ "description": "The merged object"
163
+ }
164
+ },
165
+ {
166
+ "signature": "deepMerge(target: null, sources: Record<string, unknown>[]): null",
167
+ "description": "Merges two or more objects deeply",
168
+ "params": [
169
+ {
170
+ "name": "target",
171
+ "type": "null",
172
+ "description": "The target object"
173
+ },
174
+ {
175
+ "name": "sources",
176
+ "type": "Record<string, unknown>[]",
177
+ "description": "The source objects to merge"
178
+ }
179
+ ],
180
+ "returns": {
181
+ "type": "null",
182
+ "description": "The merged object"
183
+ }
184
+ }
185
+ ],
186
+ "examples": [
187
+ {
188
+ "title": "Merge two objects deeply",
189
+ "description": "Recursively merges source properties into the target object.",
190
+ "code": "deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 })\n// => { a: 1, b: { c: 2, d: 3 }, e: 4 }"
191
+ }
192
+ ],
193
+ "sourceFile": "deepMerge.ts"
194
+ },
195
+ {
196
+ "name": "diff",
197
+ "kind": "function",
198
+ "description": "Structural object diff.\n\nReturns `true` when both inputs are deeply equal, otherwise a\nDiffResult describing the differences key by key.\n\nComparison rules:\n- Same reference \\u2192 `true`.\n- Either side is `null`/`undefined` (and not both) \\u2192 `false`.\n- Both `Date` \\u2192 epoch comparison.\n- Both arrays \\u2192 compared with `array/equalsDeep` (leaf, no diff drill-down).\n- Special objects (Map, Set, RegExp, Promise, class instances\\u2026) \\u2192 reference equality.\n- Plain objects \\u2192 key-by-key, recursing up to `options.depth` levels.\n- Mixed types (e.g. array vs object, Date vs object) \\u2192 `false`.\n\nFor a boolean wrapper see equalsDeep from this category.\nFor a one-level boolean check see equalsShallow from this category.",
45
199
  "since": "2.0.0",
46
200
  "signatures": [
47
201
  {
48
- "signature": "deepCompare(objA: object | null | undefined, objB: object | null | undefined): boolean | DeepCompareResult",
49
- "description": "Deep comparison of two objects that returns detailed information about differences.",
202
+ "signature": "diff(objA: object | null | undefined, objB: object | null | undefined, options: DiffOptions): boolean | DiffResult",
203
+ "description": "Structural object diff.\n\nReturns `true` when both inputs are deeply equal, otherwise a\nDiffResult describing the differences key by key.\n\nComparison rules:\n- Same reference \\u2192 `true`.\n- Either side is `null`/`undefined` (and not both) \\u2192 `false`.\n- Both `Date` \\u2192 epoch comparison.\n- Both arrays \\u2192 compared with `array/equalsDeep` (leaf, no diff drill-down).\n- Special objects (Map, Set, RegExp, Promise, class instances\\u2026) \\u2192 reference equality.\n- Plain objects \\u2192 key-by-key, recursing up to `options.depth` levels.\n- Mixed types (e.g. array vs object, Date vs object) \\u2192 `false`.\n\nFor a boolean wrapper see equalsDeep from this category.\nFor a one-level boolean check see equalsShallow from this category.",
50
204
  "params": [
51
205
  {
52
206
  "name": "objA",
53
207
  "type": "object | null | undefined",
54
- "description": "First object to compare (can be object, undefined, or null)"
208
+ "description": "First value (object, `null`, or `undefined`)."
55
209
  },
56
210
  {
57
211
  "name": "objB",
58
212
  "type": "object | null | undefined",
59
- "description": "Second object to compare (can be object, undefined, or null)"
213
+ "description": "Second value (object, `null`, or `undefined`)."
214
+ },
215
+ {
216
+ "name": "options",
217
+ "type": "DiffOptions",
218
+ "description": "See DiffOptions.",
219
+ "defaultValue": "{}"
60
220
  }
61
221
  ],
62
222
  "returns": {
63
- "type": "boolean | DeepCompareResult",
64
- "description": "`true` if objects are identical, `false` if incompatible types, or a `DeepCompareResult` object detailing differences"
223
+ "type": "boolean | DiffResult",
224
+ "description": "`true` when equal, otherwise a DiffResult, or `false` for incompatible types."
65
225
  }
66
226
  }
67
227
  ],
@@ -69,66 +229,104 @@
69
229
  {
70
230
  "title": "Compare nested objects",
71
231
  "description": "Deeply compares two objects, returning true when they are structurally equal.",
72
- "code": "deepCompare({ a: { b: 1 } }, { a: { b: 1 } })\n// => true"
232
+ "code": "diff({ a: { b: 1 } }, { a: { b: 1 } })\n// => true"
73
233
  },
74
234
  {
75
235
  "title": "Detect deep differences",
76
236
  "description": "Returns a detailed diff object when nested values differ.",
77
- "code": "deepCompare({ a: { b: 1 } }, { a: { b: 2 } })\n// => { a: { b: false } }"
237
+ "code": "diff({ a: { b: 1 } }, { a: { b: 2 } })\n// => { a: { b: false } }"
78
238
  }
79
239
  ],
80
- "sourceFile": "deepCompare.ts"
240
+ "sourceFile": "diff.ts",
241
+ "relatedTypes": [
242
+ {
243
+ "name": "DiffOptions",
244
+ "description": "Options for diff.",
245
+ "typeDefinition": "interface DiffOptions {\n depth?: number;\n}"
246
+ },
247
+ {
248
+ "name": "DiffResult",
249
+ "description": "Per-key diff result. Each entry tells what differs between the two\nobjects:\n- `\"onlyA\"` \\u2014 the key exists only on the first input.\n- `\"onlyB\"` \\u2014 the key exists only on the second input.\n- `false` \\u2014 both inputs have the key but the values differ.\n- nested `DiffResult` \\u2014 plain-object values that differ deeper.",
250
+ "typeDefinition": "interface DiffResult {}"
251
+ }
252
+ ]
81
253
  },
82
254
  {
83
- "name": "DeepCompareResult",
84
- "kind": "interface",
85
- "description": "Result type for deep comparison when objects are not identical",
255
+ "name": "equalsDeep",
256
+ "kind": "function",
257
+ "description": "Recursive structural object equality.\n\nBoolean wrapper around diff \\u2014 returns `true` when the two values\nare deeply equal according to the same rules. Use this when you only\nneed a yes/no answer; use diff when you also need to know\n*what* differs.\n\nFor a one-level boolean check use equalsShallow.",
86
258
  "since": "2.0.0",
87
- "signatures": [],
88
- "examples": [],
89
- "sourceFile": "deepCompare.ts"
259
+ "signatures": [
260
+ {
261
+ "signature": "equalsDeep(objA: object | null | undefined, objB: object | null | undefined): boolean",
262
+ "description": "Recursive structural object equality.\n\nBoolean wrapper around diff \\u2014 returns `true` when the two values\nare deeply equal according to the same rules. Use this when you only\nneed a yes/no answer; use diff when you also need to know\n*what* differs.\n\nFor a one-level boolean check use equalsShallow.",
263
+ "params": [
264
+ {
265
+ "name": "objA",
266
+ "type": "object | null | undefined",
267
+ "description": "First value (object, `null`, or `undefined`)."
268
+ },
269
+ {
270
+ "name": "objB",
271
+ "type": "object | null | undefined",
272
+ "description": "Second value (object, `null`, or `undefined`)."
273
+ }
274
+ ],
275
+ "returns": {
276
+ "type": "boolean",
277
+ "description": "`true` if both inputs are deeply equal, `false` otherwise."
278
+ }
279
+ }
280
+ ],
281
+ "examples": [
282
+ {
283
+ "title": "Compare nested objects",
284
+ "description": "Recursive structural equality. Returns true when the two values are deeply equal.",
285
+ "code": "equalsDeep({ a: { b: 1 } }, { a: { b: 1 } })\n// => true"
286
+ },
287
+ {
288
+ "title": "Detect deep differences",
289
+ "description": "Returns false when nested values differ.",
290
+ "code": "equalsDeep({ a: { b: 1 } }, { a: { b: 2 } })\n// => false"
291
+ }
292
+ ],
293
+ "sourceFile": "equalsDeep.ts"
90
294
  },
91
295
  {
92
- "name": "deepMerge",
296
+ "name": "equalsShallow",
93
297
  "kind": "function",
94
- "description": "Merges two or more objects deeply",
95
- "since": "1.9.0",
298
+ "description": "One-level (shallow) object equality.\n\nTwo objects are equal when they share the exact same set of own\nenumerable string keys and each pair of values satisfies strict equality\n(`===`). No recursion: nested objects/arrays are compared by reference.\n\nFalls back to strict equality when either input is `null`, `undefined`\nor not an object \\u2014 so primitives match if and only if they are `===`.\nArrays are not supported; they always return `false` (unless identical\nreferences). Use `array/equalsShallow` instead.\n\nFor recursive structural comparison use equalsDeep. For a diff\nstructure use diff.",
299
+ "since": "2.0.0",
96
300
  "signatures": [
97
301
  {
98
- "signature": "deepMerge<T extends Record<string, any>>(target: T, sources: Record<string, any>[]): T",
99
- "description": "Merges two or more objects deeply",
302
+ "signature": "equalsShallow(objA: unknown, objB: unknown): boolean",
303
+ "description": "One-level (shallow) object equality.\n\nTwo objects are equal when they share the exact same set of own\nenumerable string keys and each pair of values satisfies strict equality\n(`===`). No recursion: nested objects/arrays are compared by reference.\n\nFalls back to strict equality when either input is `null`, `undefined`\nor not an object \\u2014 so primitives match if and only if they are `===`.\nArrays are not supported; they always return `false` (unless identical\nreferences). Use `array/equalsShallow` instead.\n\nFor recursive structural comparison use equalsDeep. For a diff\nstructure use diff.",
100
304
  "params": [
101
305
  {
102
- "name": "target",
103
- "type": "T",
104
- "description": "The target object"
306
+ "name": "objA",
307
+ "type": "unknown",
308
+ "description": "First value to compare"
105
309
  },
106
310
  {
107
- "name": "sources",
108
- "type": "Record<string, any>[]",
109
- "description": "The source objects to merge"
311
+ "name": "objB",
312
+ "type": "unknown",
313
+ "description": "Second value to compare"
110
314
  }
111
315
  ],
112
316
  "returns": {
113
- "type": "T",
114
- "description": "The merged object"
115
- },
116
- "typeParameters": [
117
- {
118
- "name": "T",
119
- "constraint": "Record<string, any>"
120
- }
121
- ]
317
+ "type": "boolean",
318
+ "description": "`true` if values are shallowly equal, `false` otherwise."
319
+ }
122
320
  }
123
321
  ],
124
322
  "examples": [
125
323
  {
126
- "title": "Merge two objects deeply",
127
- "description": "Recursively merges source properties into the target object.",
128
- "code": "deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 })\n// => { a: 1, b: { c: 2, d: 3 }, e: 4 }"
324
+ "title": "Compare two equal objects",
325
+ "description": "Uses JSON.stringify for a fast comparison.",
326
+ "code": "equalsShallow({ a: 1, b: 2 }, { a: 1, b: 2 })\n// => true"
129
327
  }
130
328
  ],
131
- "sourceFile": "deepMerge.ts"
329
+ "sourceFile": "equalsShallow.ts"
132
330
  },
133
331
  {
134
332
  "name": "get",
@@ -137,12 +335,12 @@
137
335
  "since": "1.9.0",
138
336
  "signatures": [
139
337
  {
140
- "signature": "get<T = any>(obj: any, path: string, defaultValue?: T): T | undefined",
338
+ "signature": "get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined",
141
339
  "description": "Gets a value from an object using a dot-notated path",
142
340
  "params": [
143
341
  {
144
342
  "name": "obj",
145
- "type": "any",
343
+ "type": "unknown",
146
344
  "description": "The object to get value from"
147
345
  },
148
346
  {
@@ -164,7 +362,7 @@
164
362
  "typeParameters": [
165
363
  {
166
364
  "name": "T",
167
- "default": "any"
365
+ "default": "unknown"
168
366
  }
169
367
  ]
170
368
  }
@@ -184,40 +382,350 @@
184
382
  "sourceFile": "get.ts"
185
383
  },
186
384
  {
187
- "name": "quickCompare",
385
+ "name": "groupBy",
188
386
  "kind": "function",
189
- "description": "Quick comparison of two objects using JSON.stringify.\nThis is a fast but simple comparison that may not work for all edge cases.",
387
+ "description": "Groups an array of items by a key derived from each item.\n\nA thin, typed wrapper around `Object.groupBy` (ES2024) that works on\nolder targets and provides stricter return-type inference.",
388
+ "since": "next",
389
+ "signatures": [
390
+ {
391
+ "signature": "groupBy<T, K extends PropertyKey>(items: readonly T[], keyFn: function): Partial<Record<K, T[]>>",
392
+ "description": "Groups an array of items by a key derived from each item.\n\nA thin, typed wrapper around `Object.groupBy` (ES2024) that works on\nolder targets and provides stricter return-type inference.",
393
+ "params": [
394
+ {
395
+ "name": "items",
396
+ "type": "readonly T[]",
397
+ "description": "The array to group"
398
+ },
399
+ {
400
+ "name": "keyFn",
401
+ "type": "function",
402
+ "description": "Function that returns the group key for each item"
403
+ }
404
+ ],
405
+ "returns": {
406
+ "type": "Partial<Record<K, T[]>>",
407
+ "description": "A record mapping each key to the array of items with that key"
408
+ },
409
+ "typeParameters": [
410
+ {
411
+ "name": "T"
412
+ },
413
+ {
414
+ "name": "K",
415
+ "constraint": "PropertyKey"
416
+ }
417
+ ]
418
+ }
419
+ ],
420
+ "examples": [
421
+ {
422
+ "title": "Group numbers by parity",
423
+ "description": "Groups elements by the string key returned by the callback.",
424
+ "code": "groupBy([1, 2, 3, 4], n => n % 2 === 0 ? 'even' : 'odd')\n// => { odd: [1, 3], even: [2, 4] }"
425
+ },
426
+ {
427
+ "title": "Group objects by a property",
428
+ "description": "Use a property accessor as the grouping key.",
429
+ "code": "const users = [\n { name: 'Alice', role: 'admin' },\n { name: 'Bob', role: 'user' },\n { name: 'Carol', role: 'admin' },\n];\ngroupBy(users, u => u.role)\n// => { admin: [{...Alice}, {...Carol}], user: [{...Bob}] }"
430
+ }
431
+ ],
432
+ "sourceFile": "groupBy.ts"
433
+ },
434
+ {
435
+ "name": "invert",
436
+ "kind": "function",
437
+ "description": "Returns a new object with keys and values swapped.\nIf multiple keys share the same value, the last one wins.",
438
+ "since": "next",
439
+ "signatures": [
440
+ {
441
+ "signature": "invert<K extends string, V extends PropertyKey>(obj: Record<K, V>): Record<V, K>",
442
+ "description": "Returns a new object with keys and values swapped.\nIf multiple keys share the same value, the last one wins.",
443
+ "params": [
444
+ {
445
+ "name": "obj",
446
+ "type": "Record<K, V>",
447
+ "description": "The object whose keys and values are to be swapped"
448
+ }
449
+ ],
450
+ "returns": {
451
+ "type": "Record<V, K>",
452
+ "description": "A new object with values as keys and original keys as values"
453
+ },
454
+ "typeParameters": [
455
+ {
456
+ "name": "K",
457
+ "constraint": "string"
458
+ },
459
+ {
460
+ "name": "V",
461
+ "constraint": "PropertyKey"
462
+ }
463
+ ]
464
+ }
465
+ ],
466
+ "examples": [
467
+ {
468
+ "title": "Swap keys and values",
469
+ "description": "Returns a new object with keys and values swapped.",
470
+ "code": "invert({ a: 'x', b: 'y', c: 'z' })\n// => { x: 'a', y: 'b', z: 'c' }"
471
+ },
472
+ {
473
+ "title": "Build a reverse lookup map",
474
+ "description": "Useful when you have a code-to-label map and need label-to-code.",
475
+ "code": "const STATUS_LABELS = { 200: 'OK', 404: 'Not Found', 500: 'Internal Server Error' };\nconst LABEL_TO_CODE = invert(STATUS_LABELS);\n\nLABEL_TO_CODE['OK']; // => '200'"
476
+ }
477
+ ],
478
+ "sourceFile": "invert.ts"
479
+ },
480
+ {
481
+ "name": "map",
482
+ "kind": "function",
483
+ "description": "Transforms the values and/or keys of a plain object in a single pass.\n\nBoth callbacks are optional and default to identity (no transformation).\nWhen `mapValue` is omitted the original values are preserved;\nwhen `mapKey` is omitted the original keys are preserved.\n\nNote: if two different keys map to the same output key the last one wins\n(insertion order).",
484
+ "since": "next",
485
+ "signatures": [
486
+ {
487
+ "signature": "map<TObj extends Record<string, unknown>, TVal = indexedAccess, TKey extends PropertyKey = keyof TObj>(obj: TObj, mapValue?: function, mapKey?: function): Record<TKey, TVal>",
488
+ "description": "Transforms the values and/or keys of a plain object in a single pass.\n\nBoth callbacks are optional and default to identity (no transformation).\nWhen `mapValue` is omitted the original values are preserved;\nwhen `mapKey` is omitted the original keys are preserved.\n\nNote: if two different keys map to the same output key the last one wins\n(insertion order).",
489
+ "params": [
490
+ {
491
+ "name": "obj",
492
+ "type": "TObj",
493
+ "description": "The source object"
494
+ },
495
+ {
496
+ "name": "mapValue",
497
+ "type": "function",
498
+ "description": "Callback called with `(value, key)` for each entry.\n Defaults to identity.",
499
+ "optional": true
500
+ },
501
+ {
502
+ "name": "mapKey",
503
+ "type": "function",
504
+ "description": "Callback called with `(key, value)` for each entry.\n Defaults to identity.",
505
+ "optional": true
506
+ }
507
+ ],
508
+ "returns": {
509
+ "type": "Record<TKey, TVal>",
510
+ "description": "A new object with transformed keys and/or values"
511
+ },
512
+ "typeParameters": [
513
+ {
514
+ "name": "TObj",
515
+ "constraint": "Record<string, unknown>"
516
+ },
517
+ {
518
+ "name": "TVal",
519
+ "default": "indexedAccess"
520
+ },
521
+ {
522
+ "name": "TKey",
523
+ "constraint": "PropertyKey",
524
+ "default": "keyof TObj"
525
+ }
526
+ ]
527
+ }
528
+ ],
529
+ "examples": [
530
+ {
531
+ "title": "Transform values",
532
+ "description": "Maps each value of an object through a transform function.",
533
+ "code": "map({ a: 1, b: 2 }, v => v * 10)\n// => { a: 10, b: 20 }"
534
+ },
535
+ {
536
+ "title": "Transform keys",
537
+ "description": "Maps each key of an object through a transform function.",
538
+ "code": "map({ a: 1, b: 2 }, undefined, k => k.toUpperCase())\n// => { A: 1, B: 2 }"
539
+ },
540
+ {
541
+ "title": "Transform both keys and values in a single pass",
542
+ "description": "Provide both a value mapper and a key mapper to rewrite the whole object.",
543
+ "code": "map(\n { price: 100, discount: 20 },\n v => v / 100,\n k => `${k}Ratio`\n)\n// => { priceRatio: 1, discountRatio: 0.2 }"
544
+ }
545
+ ],
546
+ "sourceFile": "map.ts"
547
+ },
548
+ {
549
+ "name": "omit",
550
+ "kind": "function",
551
+ "description": "Creates a new object without the specified keys.",
190
552
  "since": "2.0.0",
191
553
  "signatures": [
192
554
  {
193
- "signature": "quickCompare(objA: unknown, objB: unknown): boolean",
194
- "description": "Quick comparison of two objects using JSON.stringify.\nThis is a fast but simple comparison that may not work for all edge cases.",
555
+ "signature": "omit<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Omit<T, K>",
556
+ "description": "Creates a new object without the specified keys.",
195
557
  "params": [
196
558
  {
197
- "name": "objA",
198
- "type": "unknown",
199
- "description": "First object to compare"
559
+ "name": "obj",
560
+ "type": "T",
561
+ "description": "The source object"
200
562
  },
201
563
  {
202
- "name": "objB",
203
- "type": "unknown",
204
- "description": "Second object to compare"
564
+ "name": "keys",
565
+ "type": "readonly K[]",
566
+ "description": "The keys to omit"
205
567
  }
206
568
  ],
207
569
  "returns": {
208
- "type": "boolean",
209
- "description": "`true` if objects are identical according to JSON.stringify, `false` otherwise"
570
+ "type": "Omit<T, K>",
571
+ "description": "A new object without the omitted keys"
572
+ },
573
+ "typeParameters": [
574
+ {
575
+ "name": "T",
576
+ "constraint": "Record<string, unknown>"
577
+ },
578
+ {
579
+ "name": "K",
580
+ "constraint": "string | number | symbol"
581
+ }
582
+ ]
583
+ },
584
+ {
585
+ "signature": "omit(obj: undefined, keys: readonly string[]): undefined",
586
+ "description": "Creates a new object without the specified keys.",
587
+ "params": [
588
+ {
589
+ "name": "obj",
590
+ "type": "undefined",
591
+ "description": "The source object"
592
+ },
593
+ {
594
+ "name": "keys",
595
+ "type": "readonly string[]",
596
+ "description": "The keys to omit"
597
+ }
598
+ ],
599
+ "returns": {
600
+ "type": "undefined",
601
+ "description": "A new object without the omitted keys"
602
+ }
603
+ },
604
+ {
605
+ "signature": "omit(obj: null, keys: readonly string[]): null",
606
+ "description": "Creates a new object without the specified keys.",
607
+ "params": [
608
+ {
609
+ "name": "obj",
610
+ "type": "null",
611
+ "description": "The source object"
612
+ },
613
+ {
614
+ "name": "keys",
615
+ "type": "readonly string[]",
616
+ "description": "The keys to omit"
617
+ }
618
+ ],
619
+ "returns": {
620
+ "type": "null",
621
+ "description": "A new object without the omitted keys"
210
622
  }
211
623
  }
212
624
  ],
213
625
  "examples": [
214
626
  {
215
- "title": "Compare two equal objects",
216
- "description": "Uses JSON.stringify for a fast comparison.",
217
- "code": "quickCompare({ a: 1, b: 2 }, { a: 1, b: 2 })\n// => true"
627
+ "title": "Omit specific keys",
628
+ "description": "Creates a new object without the specified keys.",
629
+ "code": "omit({ a: 1, b: 2, c: 3 }, ['b'])\n// => { a: 1, c: 3 }"
630
+ },
631
+ {
632
+ "title": "Remove sensitive fields",
633
+ "description": "Useful to strip sensitive data before sending to client.",
634
+ "code": "const user = { id: 1, name: 'Alice', password: 'secret', token: 'abc123' };\nomit(user, ['password', 'token'])\n// => { id: 1, name: 'Alice' }"
635
+ }
636
+ ],
637
+ "sourceFile": "omit.ts"
638
+ },
639
+ {
640
+ "name": "pick",
641
+ "kind": "function",
642
+ "description": "Creates a new object with only the specified keys.",
643
+ "since": "2.0.0",
644
+ "signatures": [
645
+ {
646
+ "signature": "pick<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Pick<T, K>",
647
+ "description": "Creates a new object with only the specified keys.",
648
+ "params": [
649
+ {
650
+ "name": "obj",
651
+ "type": "T",
652
+ "description": "The source object"
653
+ },
654
+ {
655
+ "name": "keys",
656
+ "type": "readonly K[]",
657
+ "description": "The keys to pick"
658
+ }
659
+ ],
660
+ "returns": {
661
+ "type": "Pick<T, K>",
662
+ "description": "A new object with only the picked keys"
663
+ },
664
+ "typeParameters": [
665
+ {
666
+ "name": "T",
667
+ "constraint": "Record<string, unknown>"
668
+ },
669
+ {
670
+ "name": "K",
671
+ "constraint": "string | number | symbol"
672
+ }
673
+ ]
674
+ },
675
+ {
676
+ "signature": "pick(obj: undefined, keys: readonly string[]): undefined",
677
+ "description": "Creates a new object with only the specified keys.",
678
+ "params": [
679
+ {
680
+ "name": "obj",
681
+ "type": "undefined",
682
+ "description": "The source object"
683
+ },
684
+ {
685
+ "name": "keys",
686
+ "type": "readonly string[]",
687
+ "description": "The keys to pick"
688
+ }
689
+ ],
690
+ "returns": {
691
+ "type": "undefined",
692
+ "description": "A new object with only the picked keys"
693
+ }
694
+ },
695
+ {
696
+ "signature": "pick(obj: null, keys: readonly string[]): null",
697
+ "description": "Creates a new object with only the specified keys.",
698
+ "params": [
699
+ {
700
+ "name": "obj",
701
+ "type": "null",
702
+ "description": "The source object"
703
+ },
704
+ {
705
+ "name": "keys",
706
+ "type": "readonly string[]",
707
+ "description": "The keys to pick"
708
+ }
709
+ ],
710
+ "returns": {
711
+ "type": "null",
712
+ "description": "A new object with only the picked keys"
713
+ }
714
+ }
715
+ ],
716
+ "examples": [
717
+ {
718
+ "title": "Pick specific keys",
719
+ "description": "Creates a new object with only the specified keys.",
720
+ "code": "pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])\n// => { a: 1, c: 3 }"
721
+ },
722
+ {
723
+ "title": "Extract user fields",
724
+ "description": "Useful to select only the fields you need from an object.",
725
+ "code": "const user = { id: 1, name: 'Alice', email: 'alice@example.com', password: 'secret' };\npick(user, ['id', 'name', 'email'])\n// => { id: 1, name: 'Alice', email: 'alice@example.com' }"
218
726
  }
219
727
  ],
220
- "sourceFile": "quickCompare.ts"
728
+ "sourceFile": "pick.ts"
221
729
  },
222
730
  {
223
731
  "name": "removeUndefinedNull",
@@ -286,6 +794,77 @@
286
794
  ],
287
795
  "sourceFile": "removeUndefinedNull.ts"
288
796
  },
797
+ {
798
+ "name": "safeJsonParse",
799
+ "kind": "function",
800
+ "description": "Parses a JSON string, returning `null` (or a fallback) on any parse failure.\n\nUnlike `JSON.parse`, this never throws. Invalid JSON strings and other\nparsing edge-cases resolve to `null` or the provided `fallback`.",
801
+ "since": "next",
802
+ "signatures": [
803
+ {
804
+ "signature": "safeJsonParse<T>(input: string): T | null",
805
+ "description": "Parses a JSON string, returning `null` (or a fallback) on any parse failure.\n\nUnlike `JSON.parse`, this never throws. Invalid JSON strings and other\nparsing edge-cases resolve to `null` or the provided `fallback`.",
806
+ "params": [
807
+ {
808
+ "name": "input",
809
+ "type": "string",
810
+ "description": "The JSON string to parse."
811
+ }
812
+ ],
813
+ "returns": {
814
+ "type": "T | null",
815
+ "description": "The parsed value typed as `T`, or `fallback` on failure."
816
+ },
817
+ "typeParameters": [
818
+ {
819
+ "name": "T"
820
+ }
821
+ ]
822
+ },
823
+ {
824
+ "signature": "safeJsonParse<T>(input: string, fallback: T): T",
825
+ "description": "Parses a JSON string, returning `null` (or a fallback) on any parse failure.\n\nUnlike `JSON.parse`, this never throws. Invalid JSON strings and other\nparsing edge-cases resolve to `null` or the provided `fallback`.",
826
+ "params": [
827
+ {
828
+ "name": "input",
829
+ "type": "string",
830
+ "description": "The JSON string to parse."
831
+ },
832
+ {
833
+ "name": "fallback",
834
+ "type": "T",
835
+ "description": "Value returned on failure. Defaults to `null` when omitted."
836
+ }
837
+ ],
838
+ "returns": {
839
+ "type": "T",
840
+ "description": "The parsed value typed as `T`, or `fallback` on failure."
841
+ },
842
+ "typeParameters": [
843
+ {
844
+ "name": "T"
845
+ }
846
+ ]
847
+ }
848
+ ],
849
+ "examples": [
850
+ {
851
+ "title": "Parse valid JSON",
852
+ "description": "Returns the parsed value when the input is valid JSON.",
853
+ "code": "safeJsonParse<{ a: number }>('{\"a\":1}')\n// => { a: 1 }"
854
+ },
855
+ {
856
+ "title": "Return null on invalid input",
857
+ "description": "Returns null instead of throwing when JSON is malformed.",
858
+ "code": "safeJsonParse('invalid')\n// => null"
859
+ },
860
+ {
861
+ "title": "Use a fallback value",
862
+ "description": "Returns the provided fallback when parsing fails.",
863
+ "code": "safeJsonParse('invalid', [])\n// => []"
864
+ }
865
+ ],
866
+ "sourceFile": "safeJsonParse.ts"
867
+ },
289
868
  {
290
869
  "name": "set",
291
870
  "kind": "function",
@@ -293,12 +872,12 @@
293
872
  "since": "1.9.0",
294
873
  "signatures": [
295
874
  {
296
- "signature": "set(obj: Record<string, any>, path: string, value: any): Record<string, any>",
875
+ "signature": "set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>",
297
876
  "description": "Sets a value in an object using a dot-notated path",
298
877
  "params": [
299
878
  {
300
879
  "name": "obj",
301
- "type": "Record<string, any>",
880
+ "type": "Record<string, unknown>",
302
881
  "description": "The object to set value in"
303
882
  },
304
883
  {
@@ -308,12 +887,12 @@
308
887
  },
309
888
  {
310
889
  "name": "value",
311
- "type": "any",
890
+ "type": "unknown",
312
891
  "description": "The value to set"
313
892
  }
314
893
  ],
315
894
  "returns": {
316
- "type": "Record<string, any>",
895
+ "type": "Record<string, unknown>",
317
896
  "description": "The modified object"
318
897
  }
319
898
  }