@helpers4/object 2.0.0-alpha.11 → 2.0.0-alpha.15

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 CHANGED
@@ -46,15 +46,15 @@ A set of helpers for working with URLs.
46
46
  | Name | Package | Source Code | Description |
47
47
  |------|---------|-------------|-------------|
48
48
  | array | [@helpers4/array](https://www.npmjs.com/package/@helpers4/array) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/array) | Array manipulation utilities |
49
- | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | date utilities |
49
+ | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | Date and time utility functions |
50
50
  | function | [@helpers4/function](https://www.npmjs.com/package/@helpers4/function) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/function) | Function utilities and type guards |
51
- | math | [@helpers4/math](https://www.npmjs.com/package/@helpers4/math) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/math) | math utilities |
52
- | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | number utilities |
51
+ | math | [@helpers4/math](https://www.npmjs.com/package/@helpers4/math) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/math) | Mathematical utility functions and calculations |
52
+ | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | Number utility functions and validation |
53
53
  | object | [@helpers4/object](https://www.npmjs.com/package/@helpers4/object) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/object) | Object manipulation utilities |
54
54
  | observable | [@helpers4/observable](https://www.npmjs.com/package/@helpers4/observable) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/observable) | Observable utilities and combinators |
55
55
  | promise | [@helpers4/promise](https://www.npmjs.com/package/@helpers4/promise) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/promise) | Promise utilities and error handling |
56
56
  | string | [@helpers4/string](https://www.npmjs.com/package/@helpers4/string) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/string) | String manipulation and formatting utilities |
57
- | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | type utilities |
57
+ | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | Type checking and validation utilities |
58
58
  | url | [@helpers4/url](https://www.npmjs.com/package/@helpers4/url) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/url) | URL parsing and manipulation utilities |
59
59
  | version | [@helpers4/version](https://www.npmjs.com/package/@helpers4/version) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/version) | Version string manipulation utilities |
60
60
  <!-- /AUTOMATIC-CATEGORIES-TABLE -->
package/lib/index.d.ts CHANGED
@@ -13,6 +13,8 @@
13
13
  * @since 2.0.0
14
14
  */
15
15
  declare function compact<T extends Record<string, unknown>>(obj: T): Partial<T>;
16
+ declare function compact(obj: undefined): undefined;
17
+ declare function compact(obj: null): null;
16
18
 
17
19
  /**
18
20
  * This file is part of helpers4.
@@ -61,7 +63,9 @@ declare function deepCompare(objA: object | undefined | null, objB: object | und
61
63
  * @returns The merged object
62
64
  * @since 1.9.0
63
65
  */
64
- declare function deepMerge<T extends Record<string, any>>(target: T, ...sources: Record<string, any>[]): T;
66
+ declare function deepMerge<T extends Record<string, unknown>>(target: T, ...sources: Record<string, unknown>[]): T;
67
+ declare function deepMerge(target: undefined, ...sources: Record<string, unknown>[]): undefined;
68
+ declare function deepMerge(target: null, ...sources: Record<string, unknown>[]): null;
65
69
 
66
70
  /**
67
71
  * This file is part of helpers4.
@@ -76,7 +80,7 @@ declare function deepMerge<T extends Record<string, any>>(target: T, ...sources:
76
80
  * @returns The value at the path or default value
77
81
  * @since 1.9.0
78
82
  */
79
- declare function get<T = any>(obj: any, path: string, defaultValue?: T): T | undefined;
83
+ declare function get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined;
80
84
 
81
85
  /**
82
86
  * This file is part of helpers4.
@@ -94,6 +98,8 @@ declare function get<T = any>(obj: any, path: string, defaultValue?: T): T | und
94
98
  * @since 2.0.0
95
99
  */
96
100
  declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K>;
101
+ declare function omit(obj: undefined, keys: readonly string[]): undefined;
102
+ declare function omit(obj: null, keys: readonly string[]): null;
97
103
 
98
104
  /**
99
105
  * This file is part of helpers4.
@@ -111,6 +117,8 @@ declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj:
111
117
  * @since 2.0.0
112
118
  */
113
119
  declare function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K>;
120
+ declare function pick(obj: undefined, keys: readonly string[]): undefined;
121
+ declare function pick(obj: null, keys: readonly string[]): null;
114
122
 
115
123
  /**
116
124
  * This file is part of helpers4.
@@ -155,7 +163,7 @@ declare function removeUndefinedNull(obj: undefined): undefined;
155
163
  * @returns The modified object
156
164
  * @since 1.9.0
157
165
  */
158
- declare function set(obj: Record<string, any>, path: string, value: any): Record<string, any>;
166
+ declare function set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>;
159
167
 
160
168
  /**
161
169
  * This file is part of helpers4.
package/lib/index.js CHANGED
@@ -1,19 +1,6 @@
1
1
  //#region helpers/object/compact.ts
2
- /**
3
- * This file is part of helpers4.
4
- * Copyright (C) 2025 baxyz
5
- * SPDX-License-Identifier: LGPL-3.0-or-later
6
- */
7
- /**
8
- * Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `""`, `NaN`) from an object.
9
- * @param obj - The source object
10
- * @returns A new object containing only entries with truthy values
11
- * @example
12
- * compact({ a: 1, b: null, c: '', d: 0, e: 'hello' })
13
- * // => { a: 1, e: 'hello' }
14
- * @since 2.0.0
15
- */
16
2
  function compact(obj) {
3
+ if (obj === void 0 || obj === null) return obj;
17
4
  const result = {};
18
5
  for (const key of Object.keys(obj)) if (obj[key]) result[key] = obj[key];
19
6
  return result;
@@ -171,34 +158,59 @@ function deepCompare(objA, objB) {
171
158
  return Object.keys(differences).length > 0 ? differences : true;
172
159
  }
173
160
  //#endregion
174
- //#region helpers/object/deepMerge.ts
161
+ //#region helpers/type/isPlainObject.ts
175
162
  /**
176
163
  * This file is part of helpers4.
177
164
  * Copyright (C) 2025 baxyz
178
165
  * SPDX-License-Identifier: LGPL-3.0-or-later
179
166
  */
180
167
  /**
181
- * Merges two or more objects deeply
182
- * @param target - The target object
183
- * @param sources - The source objects to merge
184
- * @returns The merged object
185
- * @since 1.9.0
168
+ * Checks if a value is a plain object.
169
+ *
170
+ * A plain object is created by `{}`, `new Object()`, or `Object.create(null)`.
171
+ * Returns `false` for arrays, Date, Map, Set, RegExp, class instances, etc.
172
+ *
173
+ * @param value - The value to check
174
+ * @returns True if value is a plain object
175
+ * @example
176
+ * isPlainObject({}) // => true
177
+ * isPlainObject({ a: 1 }) // => true
178
+ * isPlainObject(new Date()) // => false
179
+ * isPlainObject([]) // => false
180
+ * isPlainObject(null) // => false
181
+ * @since 2.0.0
182
+ */
183
+ function isPlainObject(value) {
184
+ if (value === null || typeof value !== "object") return false;
185
+ const proto = Object.getPrototypeOf(value);
186
+ return proto === Object.prototype || proto === null;
187
+ }
188
+ //#endregion
189
+ //#region helpers/object/deepMerge.ts
190
+ /**
191
+ * This file is part of helpers4.
192
+ * Copyright (C) 2025 baxyz
193
+ * SPDX-License-Identifier: LGPL-3.0-or-later
186
194
  */
195
+ var UNSAFE_KEYS$1 = new Set([
196
+ "__proto__",
197
+ "constructor",
198
+ "prototype"
199
+ ]);
187
200
  function deepMerge(target, ...sources) {
201
+ if (target === void 0 || target === null) return target;
188
202
  if (!sources.length) return target;
189
203
  const source = sources.shift();
190
204
  if (!source) return deepMerge(target, ...sources);
191
205
  for (const key in source) {
206
+ if (!Object.hasOwn(source, key) || UNSAFE_KEYS$1.has(key)) continue;
192
207
  const targetValue = target[key];
193
208
  const sourceValue = source[key];
194
- if (isObject(targetValue) && isObject(sourceValue)) target[key] = deepMerge(targetValue, sourceValue);
209
+ if (isPlainObject(targetValue) && isPlainObject(sourceValue)) target[key] = deepMerge(targetValue, sourceValue);
195
210
  else if (sourceValue !== void 0) target[key] = sourceValue;
196
211
  }
197
212
  return deepMerge(target, ...sources);
198
213
  }
199
- function isObject(item) {
200
- return item && typeof item === "object" && !Array.isArray(item);
201
- }
202
214
  //#endregion
203
215
  //#region helpers/object/get.ts
204
216
  /**
@@ -225,44 +237,16 @@ function get(obj, path, defaultValue) {
225
237
  }
226
238
  //#endregion
227
239
  //#region helpers/object/omit.ts
228
- /**
229
- * This file is part of helpers4.
230
- * Copyright (C) 2025 baxyz
231
- * SPDX-License-Identifier: LGPL-3.0-or-later
232
- */
233
- /**
234
- * Creates a new object without the specified keys.
235
- * @param obj - The source object
236
- * @param keys - The keys to omit
237
- * @returns A new object without the omitted keys
238
- * @example
239
- * omit({ a: 1, b: 2, c: 3 }, ['b'])
240
- * // => { a: 1, c: 3 }
241
- * @since 2.0.0
242
- */
243
240
  function omit(obj, keys) {
241
+ if (obj === void 0 || obj === null) return obj;
244
242
  const result = { ...obj };
245
243
  for (const key of keys) delete result[key];
246
244
  return result;
247
245
  }
248
246
  //#endregion
249
247
  //#region helpers/object/pick.ts
250
- /**
251
- * This file is part of helpers4.
252
- * Copyright (C) 2025 baxyz
253
- * SPDX-License-Identifier: LGPL-3.0-or-later
254
- */
255
- /**
256
- * Creates a new object with only the specified keys.
257
- * @param obj - The source object
258
- * @param keys - The keys to pick
259
- * @returns A new object with only the picked keys
260
- * @example
261
- * pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])
262
- * // => { a: 1, c: 3 }
263
- * @since 2.0.0
264
- */
265
248
  function pick(obj, keys) {
249
+ if (obj === void 0 || obj === null) return obj;
266
250
  const result = {};
267
251
  for (const key of keys) if (Object.prototype.hasOwnProperty.call(obj, key)) result[key] = obj[key];
268
252
  return result;
@@ -283,6 +267,9 @@ function pick(obj, keys) {
283
267
  * isNullish(undefined) // => true
284
268
  * isNullish(0) // => false
285
269
  * isNullish('') // => false
270
+ *
271
+ * @see {@link isDefined} for the inverse check (`!isNullish`)
272
+ * @see {@link isFalsy} to also catch `0`, `""`, `false`, and `NaN`
286
273
  * @since 2.0.0
287
274
  */
288
275
  function isNullish(value) {
@@ -303,10 +290,10 @@ function isNullish(value) {
303
290
  * @since 1.0.0
304
291
  */
305
292
  function removeUndefinedNull(obj) {
306
- return obj ? Object.entries(obj).filter(([_, v]) => !isNullish(v)).reduce((acc, [k, v]) => ({
307
- ...acc,
308
- [k]: v
309
- }), {}) : obj;
293
+ if (!obj) return obj;
294
+ const result = {};
295
+ for (const [k, v] of Object.entries(obj)) if (!isNullish(v)) result[k] = v;
296
+ return result;
310
297
  }
311
298
  //#endregion
312
299
  //#region helpers/object/set.ts
@@ -315,6 +302,11 @@ function removeUndefinedNull(obj) {
315
302
  * Copyright (C) 2025 baxyz
316
303
  * SPDX-License-Identifier: LGPL-3.0-or-later
317
304
  */
305
+ var UNSAFE_KEYS = new Set([
306
+ "__proto__",
307
+ "constructor",
308
+ "prototype"
309
+ ]);
318
310
  /**
319
311
  * Sets a value in an object using a dot-notated path
320
312
  * @param obj - The object to set value in
@@ -325,6 +317,7 @@ function removeUndefinedNull(obj) {
325
317
  */
326
318
  function set(obj, path, value) {
327
319
  const keys = path.split(".");
320
+ if (keys.some((k) => UNSAFE_KEYS.has(k))) return obj;
328
321
  let current = obj;
329
322
  for (let i = 0; i < keys.length - 1; i++) {
330
323
  const key = keys[i];
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/object/compact.ts","../../../helpers/object/deepClone.ts","../../../helpers/array/shallowEquals.ts","../../../helpers/date/compare.ts","../../../helpers/type/isSpecialObject.ts","../../../helpers/object/deepCompare.ts","../../../helpers/object/deepMerge.ts","../../../helpers/object/get.ts","../../../helpers/object/omit.ts","../../../helpers/object/pick.ts","../../../helpers/type/isNullish.ts","../../../helpers/object/removeUndefinedNull.ts","../../../helpers/object/set.ts","../../../helpers/object/shallowEquals.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.\n * @param obj - The source object\n * @returns A new object containing only entries with truthy values\n * @example\n * compact({ a: 1, b: null, c: '', d: 0, e: 'hello' })\n * // => { a: 1, e: 'hello' }\n * @since 2.0.0\n */\nexport function compact<T extends Record<string, unknown>>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n for (const key of Object.keys(obj) as (keyof T)[]) {\n if (obj[key]) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a deep copy of an object or array\n * @param obj - The object to clone\n * @returns Deep cloned object\n * @since 1.9.0\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as T;\n }\n\n const cloned = {} as T;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n cloned[key] = deepClone(obj[key]);\n }\n }\n\n return cloned;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Quick comparison of two arrays using JSON.stringify.\n * This is a fast but simple comparison that may not work for all edge cases.\n *\n * @param arrA - First array to compare\n * @param arrB - Second array to compare\n * @returns `true` if arrays are identical according to JSON.stringify, `false` otherwise\n * @since 2.0.0\n */\nexport function shallowEquals<T>(arrA: T[], arrB: T[]): boolean {\n try {\n return JSON.stringify(arrA) === JSON.stringify(arrB);\n } catch {\n // If JSON.stringify fails (e.g., circular references), fall back to reference equality\n return arrA === arrB;\n }\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Options for date comparison\n * @since 2.0.0\n */\nexport interface DateCompareOptions {\n /** \n * Comparison precision\n * - 'milliseconds': Compare all including milliseconds (default)\n * - 'seconds': Ignore milliseconds, compare to the second\n * - 'minutes': Ignore seconds and milliseconds, compare to the minute\n * - 'hours': Ignore minutes, seconds and milliseconds, compare to the hour\n * - 'days': Compare only the date part (ignore time completely)\n */\n precision?: 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days';\n}\n\n/**\n * Comparison of two dates.\n * \n * @param dateA - First date to compare\n * @param dateB - Second date to compare\n * @param options - Comparison options\n * @returns `true` if dates are identical according to the specified precision, `false` otherwise\n * @since 2.0.0\n */\nexport function compare(dateA: Date, dateB: Date, options: DateCompareOptions = {}): boolean {\n const { precision = 'milliseconds' } = options;\n\n if (!(dateA instanceof Date) || !(dateB instanceof Date)) {\n return dateA === dateB;\n }\n\n // Handle invalid dates\n if (isNaN(dateA.getTime()) || isNaN(dateB.getTime())) {\n return isNaN(dateA.getTime()) && isNaN(dateB.getTime());\n }\n\n switch (precision) {\n case 'days':\n return dateA.toDateString() === dateB.toDateString();\n\n case 'hours':\n const hoursA = Math.floor(dateA.getTime() / (1000 * 60 * 60));\n const hoursB = Math.floor(dateB.getTime() / (1000 * 60 * 60));\n return hoursA === hoursB;\n\n case 'minutes':\n const minutesA = Math.floor(dateA.getTime() / (1000 * 60));\n const minutesB = Math.floor(dateB.getTime() / (1000 * 60));\n return minutesA === minutesB;\n\n case 'seconds':\n const secondsA = Math.floor(dateA.getTime() / 1000);\n const secondsB = Math.floor(dateB.getTime() / 1000);\n return secondsA === secondsB;\n\n case 'milliseconds':\n default:\n return dateA.getTime() === dateB.getTime();\n }\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Determines if a value is a special object that should not have its properties compared deeply.\n * Special objects include: Date, Function, Promise, Observable, RegExp, Error, Map, Set, WeakMap, WeakSet, etc.\n * \n * @param value - The value to check\n * @returns `true` if the value is a special object, `false` otherwise\n * @since 2.0.0\n */\nexport function isSpecialObject(value: unknown): boolean {\n if (value === null || value === undefined) {\n return false;\n }\n\n // Functions are special objects\n if (typeof value === 'function') {\n return true;\n }\n\n // Non-objects are not special\n if (typeof value !== 'object') {\n return false;\n }\n\n // Arrays are not considered special objects for our purposes\n if (Array.isArray(value)) {\n return false;\n }\n\n // Check for built-in special objects\n if (\n value instanceof Date ||\n value instanceof Promise ||\n value instanceof RegExp ||\n value instanceof Error ||\n value instanceof Map ||\n value instanceof Set ||\n value instanceof WeakMap ||\n value instanceof WeakSet ||\n value instanceof ArrayBuffer ||\n value instanceof DataView\n ) {\n return true;\n }\n\n // Check for Observable (RxJS or similar)\n if (value.constructor?.name === 'Observable') {\n return true;\n }\n\n // Check for DOM elements (if in browser environment)\n if (typeof HTMLElement !== 'undefined' && value instanceof HTMLElement) {\n return true;\n }\n\n // Check for other built-in types by constructor name\n const constructorName = value.constructor?.name;\n if (constructorName && [\n 'Buffer', // Node.js Buffer\n 'URL', // Web URL API\n 'URLSearchParams',\n 'File', // Web File API\n 'Blob', // Web Blob API\n 'FormData', // Web FormData API\n 'Headers', // Web Headers API\n 'Request', // Web Request API\n 'Response', // Web Response API\n 'EventTarget', // Web EventTarget API\n 'Symbol' // Symbol objects\n ].includes(constructorName)) {\n return true;\n }\n\n return false;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { shallowEquals as shallowEqualsArray } from '../array/shallowEquals';\nimport { compare as compareDate } from '../date/compare';\nimport { isSpecialObject } from '../type/isSpecialObject';\n\n/**\n * Result type for deep comparison when objects are not identical\n * @since 2.0.0\n */\nexport interface DeepCompareResult {\n [key: string]: \"onlyA\" | \"onlyB\" | false | DeepCompareResult;\n}\n\n/**\n * Deep comparison of two objects that returns detailed information about differences.\n *\n * @param objA - First object to compare (can be object, undefined, or null)\n * @param objB - Second object to compare (can be object, undefined, or null)\n * @returns `true` if objects are identical, `false` if incompatible types, or a `DeepCompareResult` object detailing differences\n * @since 2.0.0\n */\nexport function deepCompare(objA: object | undefined | null, objB: object | undefined | null): true | false | DeepCompareResult {\n // Quick reference equality check\n if (objA === objB) {\n return true;\n }\n\n // Handle null/undefined cases\n if (objA == null || objB == null) {\n return false;\n }\n\n // Handle Date objects\n if (objA instanceof Date && objB instanceof Date) {\n return compareDate(objA, objB);\n }\n\n // Handle Arrays at root level - use shallowEquals\n if (Array.isArray(objA) && Array.isArray(objB)) {\n return shallowEqualsArray(objA, objB);\n }\n\n // If one is array and other is not\n if (Array.isArray(objA) || Array.isArray(objB)) {\n return false;\n }\n\n // Handle special objects - compare by reference only\n if (isSpecialObject(objA) || isSpecialObject(objB)) {\n return objA === objB;\n }\n\n // Handle objects - detailed comparison\n const keys = Array.from(new Set([...Object.keys(objA), ...Object.keys(objB)]));\n\n const differences: DeepCompareResult = {};\n\n for (const key of keys) {\n const hasA = key in objA;\n const hasB = key in objB;\n\n if (!hasA && hasB) {\n differences[key] = \"onlyB\";\n } else if (hasA && !hasB) {\n differences[key] = \"onlyA\";\n } else {\n // Both objects have this key - compare values\n const valueA = (objA as any)[key];\n const valueB = (objB as any)[key];\n\n // For arrays, use shallowEquals\n if (Array.isArray(valueA) && Array.isArray(valueB)) {\n if (!shallowEqualsArray(valueA, valueB)) {\n differences[key] = false;\n }\n }\n // For dates, use compareDate\n else if (valueA instanceof Date && valueB instanceof Date) {\n if (!compareDate(valueA, valueB)) {\n differences[key] = false;\n }\n }\n // For special objects, compare by reference only\n else if (isSpecialObject(valueA) || isSpecialObject(valueB)) {\n if (valueA !== valueB) {\n differences[key] = false;\n }\n }\n // For objects, recurse (only plain objects now)\n else if (\n valueA !== null && valueB !== null &&\n valueA !== undefined && valueB !== undefined &&\n typeof valueA === 'object' && typeof valueB === 'object' &&\n !isSpecialObject(valueA) && !isSpecialObject(valueB)\n ) {\n const nestedResult = deepCompare(valueA, valueB);\n if (nestedResult !== true) {\n differences[key] = nestedResult === false ? false : nestedResult;\n }\n }\n // For primitives and other types, check equality\n else if (valueA !== valueB) {\n differences[key] = false;\n }\n }\n }\n\n return Object.keys(differences).length > 0 ? differences : true;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Merges two or more objects deeply\n * @param target - The target object\n * @param sources - The source objects to merge\n * @returns The merged object\n * @since 1.9.0\n */\nexport function deepMerge<T extends Record<string, any>>(target: T, ...sources: Record<string, any>[]): T {\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (!source) return deepMerge(target, ...sources);\n\n for (const key in source) {\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (isObject(targetValue) && isObject(sourceValue)) {\n (target as any)[key] = deepMerge(targetValue, sourceValue);\n } else if (sourceValue !== undefined) {\n (target as any)[key] = sourceValue;\n }\n }\n\n return deepMerge(target, ...sources);\n}\n\nfunction isObject(item: any): item is object {\n return item && typeof item === 'object' && !Array.isArray(item);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Gets a value from an object using a dot-notated path\n * @param obj - The object to get value from\n * @param path - The dot-notated path (e.g., 'a.b.c')\n * @param defaultValue - Default value if path doesn't exist\n * @returns The value at the path or default value\n * @since 1.9.0\n */\nexport function get<T = any>(obj: any, path: string, defaultValue?: T): T | undefined {\n const keys = path.split('.');\n let result = obj;\n\n for (const key of keys) {\n if (result == null || typeof result !== 'object') {\n return defaultValue;\n }\n result = result[key];\n }\n\n return result !== undefined ? result : defaultValue;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a new object without the specified keys.\n * @param obj - The source object\n * @param keys - The keys to omit\n * @returns A new object without the omitted keys\n * @example\n * omit({ a: 1, b: 2, c: 3 }, ['b'])\n * // => { a: 1, c: 3 }\n * @since 2.0.0\n */\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(\n obj: T,\n keys: readonly K[]\n): Omit<T, K> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, K>;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a new object with only the specified keys.\n * @param obj - The source object\n * @param keys - The keys to pick\n * @returns A new object with only the picked keys\n * @example\n * pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])\n * // => { a: 1, c: 3 }\n * @since 2.0.0\n */\nexport function pick<T extends Record<string, unknown>, K extends keyof T>(\n obj: T,\n keys: readonly K[]\n): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Checks if a value is null or undefined (nullish).\n * @param value - The value to check\n * @returns True if value is null or undefined\n * @example\n * isNullish(null) // => true\n * isNullish(undefined) // => true\n * isNullish(0) // => false\n * isNullish('') // => false\n * @since 2.0.0\n */\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { isNullish } from '../type/isNullish';\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an object\n * @returns A shallow copy of the object without null or undefined values\n * @since 1.0.0\n */\nexport function removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T): Partial<T>;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj a null object\n * @returns null\n * @since 1.0.0\n */\nexport function removeUndefinedNull(obj: null): null;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an undefined object\n * @returns undefined\n * @since 1.0.0\n */\nexport function removeUndefinedNull(obj: undefined): undefined;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an object\n * @returns A shallow copy of the object without null or undefined values\n * @since 1.0.0\n */\nexport function removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T | null | undefined): Partial<T> | null | undefined {\n return obj ? Object.entries(obj)\n .filter(([_, v]) => !isNullish(v))\n .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {} as Partial<T>) : obj;\n}\n\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Sets a value in an object using a dot-notated path\n * @param obj - The object to set value in\n * @param path - The dot-notated path (e.g., 'a.b.c')\n * @param value - The value to set\n * @returns The modified object\n * @since 1.9.0\n */\nexport function set(obj: Record<string, any>, path: string, value: any): Record<string, any> {\n const keys = path.split('.');\n let current = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n\n if (!(key in current) || typeof current[key] !== 'object' || current[key] === null) {\n current[key] = {};\n }\n\n current = current[key];\n }\n\n current[keys[keys.length - 1]] = value;\n return obj;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Quick comparison of two objects using JSON.stringify.\n * This is a fast but simple comparison that may not work for all edge cases.\n *\n * @param objA - First object to compare\n * @param objB - Second object to compare\n * @returns `true` if objects are identical according to JSON.stringify, `false` otherwise\n * @since 2.0.0\n */\nexport function shallowEquals(objA: unknown, objB: unknown): boolean {\n // Quick reference equality check\n if (objA === objB) {\n return true;\n }\n\n // Handle functions - they can't be JSON.stringified reliably\n if (typeof objA === 'function' || typeof objB === 'function') {\n return objA === objB;\n }\n\n try {\n return JSON.stringify(objA) === JSON.stringify(objB);\n } catch {\n // If JSON.stringify fails (e.g., circular references), fall back to basic comparison\n return objA === objB;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/object/compact.ts","../../../helpers/object/deepClone.ts","../../../helpers/array/shallowEquals.ts","../../../helpers/date/compare.ts","../../../helpers/type/isSpecialObject.ts","../../../helpers/object/deepCompare.ts","../../../helpers/type/isPlainObject.ts","../../../helpers/object/deepMerge.ts","../../../helpers/object/get.ts","../../../helpers/object/omit.ts","../../../helpers/object/pick.ts","../../../helpers/type/isNullish.ts","../../../helpers/object/removeUndefinedNull.ts","../../../helpers/object/set.ts","../../../helpers/object/shallowEquals.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Removes all entries with falsy values (`false`, `null`, `undefined`, `0`, `\"\"`, `NaN`) from an object.\n * @param obj - The source object\n * @returns A new object containing only entries with truthy values\n * @example\n * compact({ a: 1, b: null, c: '', d: 0, e: 'hello' })\n * // => { a: 1, e: 'hello' }\n * @since 2.0.0\n */\nexport function compact<T extends Record<string, unknown>>(obj: T): Partial<T>;\nexport function compact(obj: undefined): undefined;\nexport function compact(obj: null): null;\nexport function compact<T extends Record<string, unknown>>(obj: T | undefined | null): Partial<T> | undefined | null {\n if (obj === undefined || obj === null) return obj;\n const result: Partial<T> = {};\n for (const key of Object.keys(obj) as (keyof T)[]) {\n if (obj[key]) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a deep copy of an object or array\n * @param obj - The object to clone\n * @returns Deep cloned object\n * @since 1.9.0\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as T;\n }\n\n const cloned = {} as T;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n cloned[key] = deepClone(obj[key]);\n }\n }\n\n return cloned;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Quick comparison of two arrays using JSON.stringify.\n * This is a fast but simple comparison that may not work for all edge cases.\n *\n * @param arrA - First array to compare\n * @param arrB - Second array to compare\n * @returns `true` if arrays are identical according to JSON.stringify, `false` otherwise\n * @since 2.0.0\n */\nexport function shallowEquals<T>(arrA: T[], arrB: T[]): boolean {\n try {\n return JSON.stringify(arrA) === JSON.stringify(arrB);\n } catch {\n // If JSON.stringify fails (e.g., circular references), fall back to reference equality\n return arrA === arrB;\n }\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Options for date comparison\n * @since 2.0.0\n */\nexport interface DateCompareOptions {\n /** \n * Comparison precision\n * - 'milliseconds': Compare all including milliseconds (default)\n * - 'seconds': Ignore milliseconds, compare to the second\n * - 'minutes': Ignore seconds and milliseconds, compare to the minute\n * - 'hours': Ignore minutes, seconds and milliseconds, compare to the hour\n * - 'days': Compare only the date part (ignore time completely)\n */\n precision?: 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days';\n}\n\n/**\n * Comparison of two dates.\n * \n * @param dateA - First date to compare\n * @param dateB - Second date to compare\n * @param options - Comparison options\n * @returns `true` if dates are identical according to the specified precision, `false` otherwise\n * @since 2.0.0\n */\nexport function compare(dateA: Date, dateB: Date, options: DateCompareOptions = {}): boolean {\n const { precision = 'milliseconds' } = options;\n\n if (!(dateA instanceof Date) || !(dateB instanceof Date)) {\n return dateA === dateB;\n }\n\n // Handle invalid dates\n if (isNaN(dateA.getTime()) || isNaN(dateB.getTime())) {\n return isNaN(dateA.getTime()) && isNaN(dateB.getTime());\n }\n\n switch (precision) {\n case 'days':\n return dateA.toDateString() === dateB.toDateString();\n\n case 'hours':\n const hoursA = Math.floor(dateA.getTime() / (1000 * 60 * 60));\n const hoursB = Math.floor(dateB.getTime() / (1000 * 60 * 60));\n return hoursA === hoursB;\n\n case 'minutes':\n const minutesA = Math.floor(dateA.getTime() / (1000 * 60));\n const minutesB = Math.floor(dateB.getTime() / (1000 * 60));\n return minutesA === minutesB;\n\n case 'seconds':\n const secondsA = Math.floor(dateA.getTime() / 1000);\n const secondsB = Math.floor(dateB.getTime() / 1000);\n return secondsA === secondsB;\n\n case 'milliseconds':\n default:\n return dateA.getTime() === dateB.getTime();\n }\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Determines if a value is a special object that should not have its properties compared deeply.\n * Special objects include: Date, Function, Promise, Observable, RegExp, Error, Map, Set, WeakMap, WeakSet, etc.\n * \n * @param value - The value to check\n * @returns `true` if the value is a special object, `false` otherwise\n * @since 2.0.0\n */\nexport function isSpecialObject(value: unknown): boolean {\n if (value === null || value === undefined) {\n return false;\n }\n\n // Functions are special objects\n if (typeof value === 'function') {\n return true;\n }\n\n // Non-objects are not special\n if (typeof value !== 'object') {\n return false;\n }\n\n // Arrays are not considered special objects for our purposes\n if (Array.isArray(value)) {\n return false;\n }\n\n // Check for built-in special objects\n if (\n value instanceof Date ||\n value instanceof Promise ||\n value instanceof RegExp ||\n value instanceof Error ||\n value instanceof Map ||\n value instanceof Set ||\n value instanceof WeakMap ||\n value instanceof WeakSet ||\n value instanceof ArrayBuffer ||\n value instanceof DataView\n ) {\n return true;\n }\n\n // Check for Observable (RxJS or similar)\n if (value.constructor?.name === 'Observable') {\n return true;\n }\n\n // Check for DOM elements (if in browser environment)\n if (typeof HTMLElement !== 'undefined' && value instanceof HTMLElement) {\n return true;\n }\n\n // Check for other built-in types by constructor name\n const constructorName = value.constructor?.name;\n if (constructorName && [\n 'Buffer', // Node.js Buffer\n 'URL', // Web URL API\n 'URLSearchParams',\n 'File', // Web File API\n 'Blob', // Web Blob API\n 'FormData', // Web FormData API\n 'Headers', // Web Headers API\n 'Request', // Web Request API\n 'Response', // Web Response API\n 'EventTarget', // Web EventTarget API\n 'Symbol' // Symbol objects\n ].includes(constructorName)) {\n return true;\n }\n\n return false;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { shallowEquals as shallowEqualsArray } from '../array/shallowEquals';\nimport { compare as compareDate } from '../date/compare';\nimport { isSpecialObject } from '../type/isSpecialObject';\n\n/**\n * Result type for deep comparison when objects are not identical\n * @since 2.0.0\n */\nexport interface DeepCompareResult {\n [key: string]: \"onlyA\" | \"onlyB\" | false | DeepCompareResult;\n}\n\n/**\n * Deep comparison of two objects that returns detailed information about differences.\n *\n * @param objA - First object to compare (can be object, undefined, or null)\n * @param objB - Second object to compare (can be object, undefined, or null)\n * @returns `true` if objects are identical, `false` if incompatible types, or a `DeepCompareResult` object detailing differences\n * @since 2.0.0\n */\nexport function deepCompare(objA: object | undefined | null, objB: object | undefined | null): true | false | DeepCompareResult {\n // Quick reference equality check\n if (objA === objB) {\n return true;\n }\n\n // Handle null/undefined cases\n if (objA == null || objB == null) {\n return false;\n }\n\n // Handle Date objects\n if (objA instanceof Date && objB instanceof Date) {\n return compareDate(objA, objB);\n }\n\n // Handle Arrays at root level - use shallowEquals\n if (Array.isArray(objA) && Array.isArray(objB)) {\n return shallowEqualsArray(objA, objB);\n }\n\n // If one is array and other is not\n if (Array.isArray(objA) || Array.isArray(objB)) {\n return false;\n }\n\n // Handle special objects - compare by reference only\n if (isSpecialObject(objA) || isSpecialObject(objB)) {\n return objA === objB;\n }\n\n // Handle objects - detailed comparison\n const keys = Array.from(new Set([...Object.keys(objA), ...Object.keys(objB)]));\n\n const differences: DeepCompareResult = {};\n\n for (const key of keys) {\n const hasA = key in objA;\n const hasB = key in objB;\n\n if (!hasA && hasB) {\n differences[key] = \"onlyB\";\n } else if (hasA && !hasB) {\n differences[key] = \"onlyA\";\n } else {\n // Both objects have this key - compare values\n const valueA = (objA as Record<string, unknown>)[key];\n const valueB = (objB as Record<string, unknown>)[key];\n\n // For arrays, use shallowEquals\n if (Array.isArray(valueA) && Array.isArray(valueB)) {\n if (!shallowEqualsArray(valueA, valueB)) {\n differences[key] = false;\n }\n }\n // For dates, use compareDate\n else if (valueA instanceof Date && valueB instanceof Date) {\n if (!compareDate(valueA, valueB)) {\n differences[key] = false;\n }\n }\n // For special objects, compare by reference only\n else if (isSpecialObject(valueA) || isSpecialObject(valueB)) {\n if (valueA !== valueB) {\n differences[key] = false;\n }\n }\n // For objects, recurse (only plain objects now)\n else if (\n valueA !== null && valueB !== null &&\n valueA !== undefined && valueB !== undefined &&\n typeof valueA === 'object' && typeof valueB === 'object' &&\n !isSpecialObject(valueA) && !isSpecialObject(valueB)\n ) {\n const nestedResult = deepCompare(valueA, valueB);\n if (nestedResult !== true) {\n differences[key] = nestedResult === false ? false : nestedResult;\n }\n }\n // For primitives and other types, check equality\n else if (valueA !== valueB) {\n differences[key] = false;\n }\n }\n }\n\n return Object.keys(differences).length > 0 ? differences : true;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Checks if a value is a plain object.\n *\n * A plain object is created by `{}`, `new Object()`, or `Object.create(null)`.\n * Returns `false` for arrays, Date, Map, Set, RegExp, class instances, etc.\n *\n * @param value - The value to check\n * @returns True if value is a plain object\n * @example\n * isPlainObject({}) // => true\n * isPlainObject({ a: 1 }) // => true\n * isPlainObject(new Date()) // => false\n * isPlainObject([]) // => false\n * isPlainObject(null) // => false\n * @since 2.0.0\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { isPlainObject } from '../type/isPlainObject';\n\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Merges two or more objects deeply\n * @param target - The target object\n * @param sources - The source objects to merge\n * @returns The merged object\n * @since 1.9.0\n */\nexport function deepMerge<T extends Record<string, unknown>>(target: T, ...sources: Record<string, unknown>[]): T;\nexport function deepMerge(target: undefined, ...sources: Record<string, unknown>[]): undefined;\nexport function deepMerge(target: null, ...sources: Record<string, unknown>[]): null;\nexport function deepMerge<T extends Record<string, unknown>>(target: T | undefined | null, ...sources: Record<string, unknown>[]): T | undefined | null {\n if (target === undefined || target === null) return target;\n if (!sources.length) return target;\n const source = sources.shift();\n\n if (!source) return deepMerge(target, ...sources);\n\n for (const key in source) {\n if (!Object.hasOwn(source, key) || UNSAFE_KEYS.has(key)) continue;\n\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (isPlainObject(targetValue) && isPlainObject(sourceValue)) {\n (target as Record<string, unknown>)[key] = deepMerge(targetValue as Record<string, unknown>, sourceValue as Record<string, unknown>);\n } else if (sourceValue !== undefined) {\n (target as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return deepMerge(target, ...sources);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Gets a value from an object using a dot-notated path\n * @param obj - The object to get value from\n * @param path - The dot-notated path (e.g., 'a.b.c')\n * @param defaultValue - Default value if path doesn't exist\n * @returns The value at the path or default value\n * @since 1.9.0\n */\nexport function get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined {\n const keys = path.split('.');\n let result: unknown = obj;\n\n for (const key of keys) {\n if (result == null || typeof result !== 'object') {\n return defaultValue;\n }\n result = (result as Record<string, unknown>)[key];\n }\n\n return result !== undefined ? result as T | undefined : defaultValue;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a new object without the specified keys.\n * @param obj - The source object\n * @param keys - The keys to omit\n * @returns A new object without the omitted keys\n * @example\n * omit({ a: 1, b: 2, c: 3 }, ['b'])\n * // => { a: 1, c: 3 }\n * @since 2.0.0\n */\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: readonly K[]): Omit<T, K>;\nexport function omit(obj: undefined, keys: readonly string[]): undefined;\nexport function omit(obj: null, keys: readonly string[]): null;\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(\n obj: T | undefined | null,\n keys: readonly K[]\n): Omit<T, K> | undefined | null {\n if (obj === undefined || obj === null) return obj;\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, K>;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Creates a new object with only the specified keys.\n * @param obj - The source object\n * @param keys - The keys to pick\n * @returns A new object with only the picked keys\n * @example\n * pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])\n * // => { a: 1, c: 3 }\n * @since 2.0.0\n */\nexport function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K>;\nexport function pick(obj: undefined, keys: readonly string[]): undefined;\nexport function pick(obj: null, keys: readonly string[]): null;\nexport function pick<T extends Record<string, unknown>, K extends keyof T>(\n obj: T | undefined | null,\n keys: readonly K[]\n): Pick<T, K> | undefined | null {\n if (obj === undefined || obj === null) return obj;\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Checks if a value is null or undefined (nullish).\n * @param value - The value to check\n * @returns True if value is null or undefined\n * @example\n * isNullish(null) // => true\n * isNullish(undefined) // => true\n * isNullish(0) // => false\n * isNullish('') // => false\n *\n * @see {@link isDefined} for the inverse check (`!isNullish`)\n * @see {@link isFalsy} to also catch `0`, `\"\"`, `false`, and `NaN`\n * @since 2.0.0\n */\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { isNullish } from '../type/isNullish';\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an object\n * @returns A shallow copy of the object without null or undefined values\n * @since 1.0.0\n */\nexport function removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T): Partial<T>;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj a null object\n * @returns null\n * @since 1.0.0\n */\nexport function removeUndefinedNull(obj: null): null;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an undefined object\n * @returns undefined\n * @since 1.0.0\n */\nexport function removeUndefinedNull(obj: undefined): undefined;\n\n/**\n * Remove null and undefined values from an object.\n *\n * @param obj an object\n * @returns A shallow copy of the object without null or undefined values\n * @since 1.0.0\n */\nexport function removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T | null | undefined): Partial<T> | null | undefined {\n if (!obj) return obj;\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!isNullish(v)) { result[k] = v; }\n }\n return result as Partial<T>;\n}\n\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Sets a value in an object using a dot-notated path\n * @param obj - The object to set value in\n * @param path - The dot-notated path (e.g., 'a.b.c')\n * @param value - The value to set\n * @returns The modified object\n * @since 1.9.0\n */\nexport function set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown> {\n const keys = path.split('.');\n\n if (keys.some((k) => UNSAFE_KEYS.has(k))) return obj;\n\n let current: Record<string, unknown> = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n\n if (!(key in current) || typeof current[key] !== 'object' || current[key] === null) {\n current[key] = {};\n }\n\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return obj;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Quick comparison of two objects using JSON.stringify.\n * This is a fast but simple comparison that may not work for all edge cases.\n *\n * @param objA - First object to compare\n * @param objB - Second object to compare\n * @returns `true` if objects are identical according to JSON.stringify, `false` otherwise\n * @since 2.0.0\n */\nexport function shallowEquals(objA: unknown, objB: unknown): boolean {\n // Quick reference equality check\n if (objA === objB) {\n return true;\n }\n\n // Handle functions - they can't be JSON.stringified reliably\n if (typeof objA === 'function' || typeof objB === 'function') {\n return objA === objB;\n }\n\n try {\n return JSON.stringify(objA) === JSON.stringify(objB);\n } catch {\n // If JSON.stringify fails (e.g., circular references), fall back to basic comparison\n return objA === objB;\n }\n}\n"],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,520 @@
1
+ # @helpers4/object
2
+
3
+ > Tree-shakable TypeScript utility functions for the `object` domain.
4
+ > Package: `@helpers4/object` — Version: 2.0.0-alpha.15
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
+ | `DeepCompareResult` | Result type for deep comparison when objects are not identical |
29
+ | `deepMerge` | Merges two or more objects deeply |
30
+ | `get` | Gets a value from an object using a dot-notated path |
31
+ | `omit` | Creates a new object without the specified keys. |
32
+ | `pick` | Creates a new object with only the specified keys. |
33
+ | `removeUndefinedNull` | Remove null and undefined values from an object. |
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
+ ### `DeepCompareResult`
174
+
175
+ Result type for deep comparison when objects are not identical
176
+
177
+ ---
178
+
179
+ ### `deepMerge`
180
+
181
+ Merges two or more objects deeply
182
+
183
+ ```typescript
184
+ import { deepMerge } from '@helpers4/object';
185
+
186
+ deepMerge<T extends Record<string, unknown>>(target: T, sources: Record<string, unknown>[]): T
187
+ ```
188
+
189
+ **Parameters:**
190
+
191
+ - `target: T` — The target object
192
+ - `sources: Record<string, unknown>[]` — The source objects to merge
193
+
194
+ **Returns:** `T` — The merged object
195
+
196
+ ```typescript
197
+ import { deepMerge } from '@helpers4/object';
198
+
199
+ deepMerge(target: undefined, sources: Record<string, unknown>[]): undefined
200
+ ```
201
+
202
+ **Parameters:**
203
+
204
+ - `target: undefined` — The target object
205
+ - `sources: Record<string, unknown>[]` — The source objects to merge
206
+
207
+ **Returns:** `undefined` — The merged object
208
+
209
+ ```typescript
210
+ import { deepMerge } from '@helpers4/object';
211
+
212
+ deepMerge(target: null, sources: Record<string, unknown>[]): null
213
+ ```
214
+
215
+ **Parameters:**
216
+
217
+ - `target: null` — The target object
218
+ - `sources: Record<string, unknown>[]` — The source objects to merge
219
+
220
+ **Returns:** `null` — The merged object
221
+
222
+ **Examples:**
223
+
224
+ *Merge two objects deeply*
225
+
226
+ Recursively merges source properties into the target object.
227
+
228
+ ```typescript
229
+ deepMerge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 })
230
+ // => { a: 1, b: { c: 2, d: 3 }, e: 4 }
231
+ ```
232
+
233
+ ---
234
+
235
+ ### `get`
236
+
237
+ Gets a value from an object using a dot-notated path
238
+
239
+ ```typescript
240
+ import { get } from '@helpers4/object';
241
+
242
+ get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined
243
+ ```
244
+
245
+ **Parameters:**
246
+
247
+ - `obj: unknown` — The object to get value from
248
+ - `path: string` — The dot-notated path (e.g., 'a.b.c')
249
+ - `defaultValue?: T` — Default value if path doesn't exist
250
+
251
+ **Returns:** `T | undefined` — The value at the path or default value
252
+
253
+ **Examples:**
254
+
255
+ *Access a nested property*
256
+
257
+ Uses a dot-notated path to retrieve a deeply nested value.
258
+
259
+ ```typescript
260
+ get({ a: { b: { c: 42 } } }, 'a.b.c')
261
+ // => 42
262
+ ```
263
+
264
+ *Return default for missing path*
265
+
266
+ Returns the default value when the path does not exist.
267
+
268
+ ```typescript
269
+ get({ a: 1 }, 'b.c', 'default')
270
+ // => 'default'
271
+ ```
272
+
273
+ ---
274
+
275
+ ### `omit`
276
+
277
+ Creates a new object without the specified keys.
278
+
279
+ ```typescript
280
+ import { omit } from '@helpers4/object';
281
+
282
+ omit<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Omit<T, K>
283
+ ```
284
+
285
+ **Parameters:**
286
+
287
+ - `obj: T` — The source object
288
+ - `keys: readonly K[]` — The keys to omit
289
+
290
+ **Returns:** `Omit<T, K>` — A new object without the omitted keys
291
+
292
+ ```typescript
293
+ import { omit } from '@helpers4/object';
294
+
295
+ omit(obj: undefined, keys: readonly string[]): undefined
296
+ ```
297
+
298
+ **Parameters:**
299
+
300
+ - `obj: undefined` — The source object
301
+ - `keys: readonly string[]` — The keys to omit
302
+
303
+ **Returns:** `undefined` — A new object without the omitted keys
304
+
305
+ ```typescript
306
+ import { omit } from '@helpers4/object';
307
+
308
+ omit(obj: null, keys: readonly string[]): null
309
+ ```
310
+
311
+ **Parameters:**
312
+
313
+ - `obj: null` — The source object
314
+ - `keys: readonly string[]` — The keys to omit
315
+
316
+ **Returns:** `null` — A new object without the omitted keys
317
+
318
+ **Examples:**
319
+
320
+ *Omit specific keys*
321
+
322
+ Creates a new object without the specified keys.
323
+
324
+ ```typescript
325
+ omit({ a: 1, b: 2, c: 3 }, ['b'])
326
+ // => { a: 1, c: 3 }
327
+ ```
328
+
329
+ *Remove sensitive fields*
330
+
331
+ Useful to strip sensitive data before sending to client.
332
+
333
+ ```typescript
334
+ const user = { id: 1, name: 'Alice', password: 'secret', token: 'abc123' };
335
+ omit(user, ['password', 'token'])
336
+ // => { id: 1, name: 'Alice' }
337
+ ```
338
+
339
+ ---
340
+
341
+ ### `pick`
342
+
343
+ Creates a new object with only the specified keys.
344
+
345
+ ```typescript
346
+ import { pick } from '@helpers4/object';
347
+
348
+ pick<T extends Record<string, unknown>, K extends string | number | symbol>(obj: T, keys: readonly K[]): Pick<T, K>
349
+ ```
350
+
351
+ **Parameters:**
352
+
353
+ - `obj: T` — The source object
354
+ - `keys: readonly K[]` — The keys to pick
355
+
356
+ **Returns:** `Pick<T, K>` — A new object with only the picked keys
357
+
358
+ ```typescript
359
+ import { pick } from '@helpers4/object';
360
+
361
+ pick(obj: undefined, keys: readonly string[]): undefined
362
+ ```
363
+
364
+ **Parameters:**
365
+
366
+ - `obj: undefined` — The source object
367
+ - `keys: readonly string[]` — The keys to pick
368
+
369
+ **Returns:** `undefined` — A new object with only the picked keys
370
+
371
+ ```typescript
372
+ import { pick } from '@helpers4/object';
373
+
374
+ pick(obj: null, keys: readonly string[]): null
375
+ ```
376
+
377
+ **Parameters:**
378
+
379
+ - `obj: null` — The source object
380
+ - `keys: readonly string[]` — The keys to pick
381
+
382
+ **Returns:** `null` — A new object with only the picked keys
383
+
384
+ **Examples:**
385
+
386
+ *Pick specific keys*
387
+
388
+ Creates a new object with only the specified keys.
389
+
390
+ ```typescript
391
+ pick({ a: 1, b: 2, c: 3 }, ['a', 'c'])
392
+ // => { a: 1, c: 3 }
393
+ ```
394
+
395
+ *Extract user fields*
396
+
397
+ Useful to select only the fields you need from an object.
398
+
399
+ ```typescript
400
+ const user = { id: 1, name: 'Alice', email: 'alice@example.com', password: 'secret' };
401
+ pick(user, ['id', 'name', 'email'])
402
+ // => { id: 1, name: 'Alice', email: 'alice@example.com' }
403
+ ```
404
+
405
+ ---
406
+
407
+ ### `removeUndefinedNull`
408
+
409
+ Remove null and undefined values from an object.
410
+
411
+ ```typescript
412
+ import { removeUndefinedNull } from '@helpers4/object';
413
+
414
+ removeUndefinedNull<T extends Record<string, string | number | boolean | null | undefined>>(obj: T): Partial<T>
415
+ ```
416
+
417
+ **Parameters:**
418
+
419
+ - `obj: T` — an object
420
+
421
+ **Returns:** `Partial<T>` — A shallow copy of the object without null or undefined values
422
+
423
+ ```typescript
424
+ import { removeUndefinedNull } from '@helpers4/object';
425
+
426
+ removeUndefinedNull(obj: null): null
427
+ ```
428
+
429
+ **Parameters:**
430
+
431
+ - `obj: null` — a null object
432
+
433
+ **Returns:** `null` — null
434
+
435
+ ```typescript
436
+ import { removeUndefinedNull } from '@helpers4/object';
437
+
438
+ removeUndefinedNull(obj: undefined): undefined
439
+ ```
440
+
441
+ **Parameters:**
442
+
443
+ - `obj: undefined` — an undefined object
444
+
445
+ **Returns:** `undefined` — undefined
446
+
447
+ **Examples:**
448
+
449
+ *Strip null and undefined values*
450
+
451
+ Returns a shallow copy of the object without null or undefined properties.
452
+
453
+ ```typescript
454
+ removeUndefinedNull({ a: 1, b: null, c: undefined, d: 'ok' })
455
+ // => { a: 1, d: 'ok' }
456
+ ```
457
+
458
+ ---
459
+
460
+ ### `set`
461
+
462
+ Sets a value in an object using a dot-notated path
463
+
464
+ ```typescript
465
+ import { set } from '@helpers4/object';
466
+
467
+ set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>
468
+ ```
469
+
470
+ **Parameters:**
471
+
472
+ - `obj: Record<string, unknown>` — The object to set value in
473
+ - `path: string` — The dot-notated path (e.g., 'a.b.c')
474
+ - `value: unknown` — The value to set
475
+
476
+ **Returns:** `Record<string, unknown>` — The modified object
477
+
478
+ **Examples:**
479
+
480
+ *Set a nested property*
481
+
482
+ Creates intermediate objects as needed along the dot-notated path.
483
+
484
+ ```typescript
485
+ set({}, 'a.b.c', 42)
486
+ // => { a: { b: { c: 42 } } }
487
+ ```
488
+
489
+ ---
490
+
491
+ ### `shallowEquals`
492
+
493
+ Quick comparison of two objects using JSON.stringify.
494
+ This is a fast but simple comparison that may not work for all edge cases.
495
+
496
+ ```typescript
497
+ import { shallowEquals } from '@helpers4/object';
498
+
499
+ shallowEquals(objA: unknown, objB: unknown): boolean
500
+ ```
501
+
502
+ **Parameters:**
503
+
504
+ - `objA: unknown` — First object to compare
505
+ - `objB: unknown` — Second object to compare
506
+
507
+ **Returns:** `boolean` — `true` if objects are identical according to JSON.stringify, `false` otherwise
508
+
509
+ **Examples:**
510
+
511
+ *Compare two equal objects*
512
+
513
+ Uses JSON.stringify for a fast comparison.
514
+
515
+ ```typescript
516
+ shallowEquals({ a: 1, b: 2 }, { a: 1, b: 2 })
517
+ // => true
518
+ ```
519
+
520
+ ---
package/meta/api.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "category": "object",
3
- "version": "2.0.0-alpha.11",
3
+ "version": "2.0.0-alpha.15",
4
4
  "functions": [
5
5
  {
6
6
  "name": "compact",
@@ -28,6 +28,36 @@
28
28
  "constraint": "Record<string, unknown>"
29
29
  }
30
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
+ }
31
61
  }
32
62
  ],
33
63
  "examples": [
@@ -137,7 +167,7 @@
137
167
  "since": "1.9.0",
138
168
  "signatures": [
139
169
  {
140
- "signature": "deepMerge<T extends Record<string, any>>(target: T, sources: Record<string, any>[]): T",
170
+ "signature": "deepMerge<T extends Record<string, unknown>>(target: T, sources: Record<string, unknown>[]): T",
141
171
  "description": "Merges two or more objects deeply",
142
172
  "params": [
143
173
  {
@@ -147,7 +177,7 @@
147
177
  },
148
178
  {
149
179
  "name": "sources",
150
- "type": "Record<string, any>[]",
180
+ "type": "Record<string, unknown>[]",
151
181
  "description": "The source objects to merge"
152
182
  }
153
183
  ],
@@ -158,9 +188,49 @@
158
188
  "typeParameters": [
159
189
  {
160
190
  "name": "T",
161
- "constraint": "Record<string, any>"
191
+ "constraint": "Record<string, unknown>"
162
192
  }
163
193
  ]
194
+ },
195
+ {
196
+ "signature": "deepMerge(target: undefined, sources: Record<string, unknown>[]): undefined",
197
+ "description": "Merges two or more objects deeply",
198
+ "params": [
199
+ {
200
+ "name": "target",
201
+ "type": "undefined",
202
+ "description": "The target object"
203
+ },
204
+ {
205
+ "name": "sources",
206
+ "type": "Record<string, unknown>[]",
207
+ "description": "The source objects to merge"
208
+ }
209
+ ],
210
+ "returns": {
211
+ "type": "undefined",
212
+ "description": "The merged object"
213
+ }
214
+ },
215
+ {
216
+ "signature": "deepMerge(target: null, sources: Record<string, unknown>[]): null",
217
+ "description": "Merges two or more objects deeply",
218
+ "params": [
219
+ {
220
+ "name": "target",
221
+ "type": "null",
222
+ "description": "The target object"
223
+ },
224
+ {
225
+ "name": "sources",
226
+ "type": "Record<string, unknown>[]",
227
+ "description": "The source objects to merge"
228
+ }
229
+ ],
230
+ "returns": {
231
+ "type": "null",
232
+ "description": "The merged object"
233
+ }
164
234
  }
165
235
  ],
166
236
  "examples": [
@@ -179,12 +249,12 @@
179
249
  "since": "1.9.0",
180
250
  "signatures": [
181
251
  {
182
- "signature": "get<T = any>(obj: any, path: string, defaultValue?: T): T | undefined",
252
+ "signature": "get<T = unknown>(obj: unknown, path: string, defaultValue?: T): T | undefined",
183
253
  "description": "Gets a value from an object using a dot-notated path",
184
254
  "params": [
185
255
  {
186
256
  "name": "obj",
187
- "type": "any",
257
+ "type": "unknown",
188
258
  "description": "The object to get value from"
189
259
  },
190
260
  {
@@ -206,7 +276,7 @@
206
276
  "typeParameters": [
207
277
  {
208
278
  "name": "T",
209
- "default": "any"
279
+ "default": "unknown"
210
280
  }
211
281
  ]
212
282
  }
@@ -260,6 +330,46 @@
260
330
  "constraint": "string | number | symbol"
261
331
  }
262
332
  ]
333
+ },
334
+ {
335
+ "signature": "omit(obj: undefined, keys: readonly string[]): undefined",
336
+ "description": "Creates a new object without the specified keys.",
337
+ "params": [
338
+ {
339
+ "name": "obj",
340
+ "type": "undefined",
341
+ "description": "The source object"
342
+ },
343
+ {
344
+ "name": "keys",
345
+ "type": "readonly string[]",
346
+ "description": "The keys to omit"
347
+ }
348
+ ],
349
+ "returns": {
350
+ "type": "undefined",
351
+ "description": "A new object without the omitted keys"
352
+ }
353
+ },
354
+ {
355
+ "signature": "omit(obj: null, keys: readonly string[]): null",
356
+ "description": "Creates a new object without the specified keys.",
357
+ "params": [
358
+ {
359
+ "name": "obj",
360
+ "type": "null",
361
+ "description": "The source object"
362
+ },
363
+ {
364
+ "name": "keys",
365
+ "type": "readonly string[]",
366
+ "description": "The keys to omit"
367
+ }
368
+ ],
369
+ "returns": {
370
+ "type": "null",
371
+ "description": "A new object without the omitted keys"
372
+ }
263
373
  }
264
374
  ],
265
375
  "examples": [
@@ -311,6 +421,46 @@
311
421
  "constraint": "string | number | symbol"
312
422
  }
313
423
  ]
424
+ },
425
+ {
426
+ "signature": "pick(obj: undefined, keys: readonly string[]): undefined",
427
+ "description": "Creates a new object with only the specified keys.",
428
+ "params": [
429
+ {
430
+ "name": "obj",
431
+ "type": "undefined",
432
+ "description": "The source object"
433
+ },
434
+ {
435
+ "name": "keys",
436
+ "type": "readonly string[]",
437
+ "description": "The keys to pick"
438
+ }
439
+ ],
440
+ "returns": {
441
+ "type": "undefined",
442
+ "description": "A new object with only the picked keys"
443
+ }
444
+ },
445
+ {
446
+ "signature": "pick(obj: null, keys: readonly string[]): null",
447
+ "description": "Creates a new object with only the specified keys.",
448
+ "params": [
449
+ {
450
+ "name": "obj",
451
+ "type": "null",
452
+ "description": "The source object"
453
+ },
454
+ {
455
+ "name": "keys",
456
+ "type": "readonly string[]",
457
+ "description": "The keys to pick"
458
+ }
459
+ ],
460
+ "returns": {
461
+ "type": "null",
462
+ "description": "A new object with only the picked keys"
463
+ }
314
464
  }
315
465
  ],
316
466
  "examples": [
@@ -401,12 +551,12 @@
401
551
  "since": "1.9.0",
402
552
  "signatures": [
403
553
  {
404
- "signature": "set(obj: Record<string, any>, path: string, value: any): Record<string, any>",
554
+ "signature": "set(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>",
405
555
  "description": "Sets a value in an object using a dot-notated path",
406
556
  "params": [
407
557
  {
408
558
  "name": "obj",
409
- "type": "Record<string, any>",
559
+ "type": "Record<string, unknown>",
410
560
  "description": "The object to set value in"
411
561
  },
412
562
  {
@@ -416,12 +566,12 @@
416
566
  },
417
567
  {
418
568
  "name": "value",
419
- "type": "any",
569
+ "type": "unknown",
420
570
  "description": "The value to set"
421
571
  }
422
572
  ],
423
573
  "returns": {
424
- "type": "Record<string, any>",
574
+ "type": "Record<string, unknown>",
425
575
  "description": "The modified object"
426
576
  }
427
577
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "category": "object",
3
+ "label": "Object",
4
+ "smallDescription": "Object manipulation utilities",
5
+ "description": "Utilities for working with objects including property removal, filtering, and object transformation"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helpers4/object",
3
- "version": "2.0.0-alpha.11",
3
+ "version": "2.0.0-alpha.15",
4
4
  "description": "A set of helpers in TS/JS, compatible with tree-shaking, for object.",
5
5
  "author": "baxyz <baxy@etik.com>",
6
6
  "license": "LGPL-3.0",
@@ -21,6 +21,7 @@
21
21
  "./meta/api.json": "./meta/api.json",
22
22
  "./meta/examples.json": "./meta/examples.json",
23
23
  "./meta/licenses.json": "./meta/licenses.json",
24
+ "./llms.txt": "./llms.txt",
24
25
  "./package.json": "./package.json"
25
26
  },
26
27
  "keywords": [
@@ -42,6 +43,7 @@
42
43
  "lib/index.d.ts",
43
44
  "lib/index.js.map",
44
45
  "meta/",
46
+ "llms.txt",
45
47
  "LICENSE.md",
46
48
  "package.json",
47
49
  "README.md"