@fluixi/utils 1.0.0-alpha.53
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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/lib/array/advanced.cjs +1 -0
- package/dist/lib/array/advanced.d.ts +1116 -0
- package/dist/lib/array/advanced.d.ts.map +1 -0
- package/dist/lib/array/advanced.js +2429 -0
- package/dist/lib/array/advanced.mjs +1 -0
- package/dist/lib/array/array.cjs +1 -0
- package/dist/lib/array/array.d.ts +6 -0
- package/dist/lib/array/array.d.ts.map +1 -0
- package/dist/lib/array/array.js +31 -0
- package/dist/lib/array/array.mjs +1 -0
- package/dist/lib/array/index.cjs +1 -0
- package/dist/lib/array/index.d.ts +4 -0
- package/dist/lib/array/index.d.ts.map +1 -0
- package/dist/lib/array/index.js +3 -0
- package/dist/lib/array/index.mjs +1 -0
- package/dist/lib/array/utils.cjs +1 -0
- package/dist/lib/array/utils.d.ts +100 -0
- package/dist/lib/array/utils.d.ts.map +1 -0
- package/dist/lib/array/utils.js +165 -0
- package/dist/lib/array/utils.mjs +1 -0
- package/dist/lib/color/color.cjs +1 -0
- package/dist/lib/color/color.d.ts +366 -0
- package/dist/lib/color/color.d.ts.map +1 -0
- package/dist/lib/color/color.js +722 -0
- package/dist/lib/color/color.mjs +1 -0
- package/dist/lib/color/constants.cjs +1 -0
- package/dist/lib/color/constants.d.ts +361 -0
- package/dist/lib/color/constants.d.ts.map +1 -0
- package/dist/lib/color/constants.js +358 -0
- package/dist/lib/color/constants.mjs +1 -0
- package/dist/lib/color/conversions.cjs +1 -0
- package/dist/lib/color/conversions.d.ts +166 -0
- package/dist/lib/color/conversions.d.ts.map +1 -0
- package/dist/lib/color/conversions.js +766 -0
- package/dist/lib/color/conversions.mjs +1 -0
- package/dist/lib/color/helpers.cjs +1 -0
- package/dist/lib/color/helpers.d.ts +75 -0
- package/dist/lib/color/helpers.d.ts.map +1 -0
- package/dist/lib/color/helpers.js +419 -0
- package/dist/lib/color/helpers.mjs +1 -0
- package/dist/lib/color/index.cjs +1 -0
- package/dist/lib/color/index.d.ts +12 -0
- package/dist/lib/color/index.d.ts.map +1 -0
- package/dist/lib/color/index.js +15 -0
- package/dist/lib/color/index.mjs +1 -0
- package/dist/lib/color/types.cjs +1 -0
- package/dist/lib/color/types.d.ts +179 -0
- package/dist/lib/color/types.d.ts.map +1 -0
- package/dist/lib/color/types.js +1 -0
- package/dist/lib/color/types.mjs +0 -0
- package/dist/lib/color/utils.cjs +1 -0
- package/dist/lib/color/utils.d.ts +199 -0
- package/dist/lib/color/utils.d.ts.map +1 -0
- package/dist/lib/color/utils.js +858 -0
- package/dist/lib/color/utils.mjs +1 -0
- package/dist/lib/compare/comparators.cjs +1 -0
- package/dist/lib/compare/comparators.d.ts +65 -0
- package/dist/lib/compare/comparators.d.ts.map +1 -0
- package/dist/lib/compare/comparators.js +210 -0
- package/dist/lib/compare/comparators.mjs +1 -0
- package/dist/lib/compare/index.cjs +1 -0
- package/dist/lib/compare/index.d.ts +2 -0
- package/dist/lib/compare/index.d.ts.map +1 -0
- package/dist/lib/compare/index.js +1 -0
- package/dist/lib/compare/index.mjs +1 -0
- package/dist/lib/crypto/hash.cjs +1 -0
- package/dist/lib/crypto/hash.d.ts +6 -0
- package/dist/lib/crypto/hash.d.ts.map +1 -0
- package/dist/lib/crypto/hash.js +53 -0
- package/dist/lib/crypto/hash.mjs +1 -0
- package/dist/lib/crypto/index.cjs +1 -0
- package/dist/lib/crypto/index.d.ts +2 -0
- package/dist/lib/crypto/index.d.ts.map +1 -0
- package/dist/lib/crypto/index.js +1 -0
- package/dist/lib/crypto/index.mjs +1 -0
- package/dist/lib/dom/events.cjs +1 -0
- package/dist/lib/dom/events.d.ts +159 -0
- package/dist/lib/dom/events.d.ts.map +1 -0
- package/dist/lib/dom/events.js +50 -0
- package/dist/lib/dom/events.mjs +1 -0
- package/dist/lib/dom/index.cjs +1 -0
- package/dist/lib/dom/index.d.ts +3 -0
- package/dist/lib/dom/index.d.ts.map +1 -0
- package/dist/lib/dom/index.js +2 -0
- package/dist/lib/dom/index.mjs +1 -0
- package/dist/lib/dom/utils.cjs +1 -0
- package/dist/lib/dom/utils.d.ts +6 -0
- package/dist/lib/dom/utils.d.ts.map +1 -0
- package/dist/lib/dom/utils.js +37 -0
- package/dist/lib/dom/utils.mjs +1 -0
- package/dist/lib/functions/functions.cjs +1 -0
- package/dist/lib/functions/functions.d.ts +329 -0
- package/dist/lib/functions/functions.d.ts.map +1 -0
- package/dist/lib/functions/functions.js +585 -0
- package/dist/lib/functions/functions.mjs +1 -0
- package/dist/lib/functions/index.cjs +1 -0
- package/dist/lib/functions/index.d.ts +3 -0
- package/dist/lib/functions/index.d.ts.map +1 -0
- package/dist/lib/functions/index.js +1 -0
- package/dist/lib/functions/index.mjs +1 -0
- package/dist/lib/functions/types.cjs +1 -0
- package/dist/lib/functions/types.d.ts +2 -0
- package/dist/lib/functions/types.d.ts.map +1 -0
- package/dist/lib/functions/types.js +1 -0
- package/dist/lib/functions/types.mjs +0 -0
- package/dist/lib/helpers.cjs +1 -0
- package/dist/lib/helpers.d.ts +13 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/dist/lib/helpers.js +66 -0
- package/dist/lib/helpers.mjs +1 -0
- package/dist/lib/index.cjs +1 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +8 -0
- package/dist/lib/index.mjs +1 -0
- package/dist/lib/maths/constants.cjs +1 -0
- package/dist/lib/maths/constants.d.ts +84 -0
- package/dist/lib/maths/constants.d.ts.map +1 -0
- package/dist/lib/maths/constants.js +79 -0
- package/dist/lib/maths/constants.mjs +1 -0
- package/dist/lib/maths/fn/advanced.cjs +1 -0
- package/dist/lib/maths/fn/advanced.d.ts +149 -0
- package/dist/lib/maths/fn/advanced.d.ts.map +1 -0
- package/dist/lib/maths/fn/advanced.js +264 -0
- package/dist/lib/maths/fn/advanced.mjs +1 -0
- package/dist/lib/maths/fn/basic.cjs +1 -0
- package/dist/lib/maths/fn/basic.d.ts +182 -0
- package/dist/lib/maths/fn/basic.d.ts.map +1 -0
- package/dist/lib/maths/fn/basic.js +343 -0
- package/dist/lib/maths/fn/basic.mjs +1 -0
- package/dist/lib/maths/fn/complex.cjs +1 -0
- package/dist/lib/maths/fn/complex.d.ts +153 -0
- package/dist/lib/maths/fn/complex.d.ts.map +1 -0
- package/dist/lib/maths/fn/complex.js +383 -0
- package/dist/lib/maths/fn/complex.mjs +1 -0
- package/dist/lib/maths/fn/index.cjs +1 -0
- package/dist/lib/maths/fn/index.d.ts +10 -0
- package/dist/lib/maths/fn/index.d.ts.map +1 -0
- package/dist/lib/maths/fn/index.js +9 -0
- package/dist/lib/maths/fn/index.mjs +1 -0
- package/dist/lib/maths/fn/trigo.cjs +1 -0
- package/dist/lib/maths/fn/trigo.d.ts +147 -0
- package/dist/lib/maths/fn/trigo.d.ts.map +1 -0
- package/dist/lib/maths/fn/trigo.js +227 -0
- package/dist/lib/maths/fn/trigo.mjs +1 -0
- package/dist/lib/maths/fn/vector.cjs +1 -0
- package/dist/lib/maths/fn/vector.d.ts +512 -0
- package/dist/lib/maths/fn/vector.d.ts.map +1 -0
- package/dist/lib/maths/fn/vector.js +1136 -0
- package/dist/lib/maths/fn/vector.mjs +1 -0
- package/dist/lib/maths/formatter.cjs +1 -0
- package/dist/lib/maths/formatter.d.ts +35 -0
- package/dist/lib/maths/formatter.d.ts.map +1 -0
- package/dist/lib/maths/formatter.js +56 -0
- package/dist/lib/maths/formatter.mjs +1 -0
- package/dist/lib/maths/guards.cjs +1 -0
- package/dist/lib/maths/guards.d.ts +166 -0
- package/dist/lib/maths/guards.d.ts.map +1 -0
- package/dist/lib/maths/guards.js +315 -0
- package/dist/lib/maths/guards.mjs +1 -0
- package/dist/lib/maths/index.cjs +1 -0
- package/dist/lib/maths/index.d.ts +24 -0
- package/dist/lib/maths/index.d.ts.map +1 -0
- package/dist/lib/maths/index.js +29 -0
- package/dist/lib/maths/index.mjs +1 -0
- package/dist/lib/maths/parser.cjs +1 -0
- package/dist/lib/maths/parser.d.ts +20 -0
- package/dist/lib/maths/parser.d.ts.map +1 -0
- package/dist/lib/maths/parser.js +78 -0
- package/dist/lib/maths/parser.mjs +1 -0
- package/dist/lib/maths/random.cjs +1 -0
- package/dist/lib/maths/random.d.ts +27 -0
- package/dist/lib/maths/random.d.ts.map +1 -0
- package/dist/lib/maths/random.js +49 -0
- package/dist/lib/maths/random.mjs +1 -0
- package/dist/lib/maths/types/advanced.cjs +1 -0
- package/dist/lib/maths/types/advanced.d.ts +357 -0
- package/dist/lib/maths/types/advanced.d.ts.map +1 -0
- package/dist/lib/maths/types/advanced.js +5 -0
- package/dist/lib/maths/types/advanced.mjs +0 -0
- package/dist/lib/maths/types/basic.cjs +1 -0
- package/dist/lib/maths/types/basic.d.ts +95 -0
- package/dist/lib/maths/types/basic.d.ts.map +1 -0
- package/dist/lib/maths/types/basic.js +5 -0
- package/dist/lib/maths/types/basic.mjs +0 -0
- package/dist/lib/maths/types/index.cjs +1 -0
- package/dist/lib/maths/types/index.d.ts +4 -0
- package/dist/lib/maths/types/index.d.ts.map +1 -0
- package/dist/lib/maths/types/index.js +3 -0
- package/dist/lib/maths/types/index.mjs +0 -0
- package/dist/lib/maths/types/negative.cjs +1 -0
- package/dist/lib/maths/types/negative.d.ts +51 -0
- package/dist/lib/maths/types/negative.d.ts.map +1 -0
- package/dist/lib/maths/types/negative.js +5 -0
- package/dist/lib/maths/types/negative.mjs +0 -0
- package/dist/lib/maths/types/operations.cjs +1 -0
- package/dist/lib/maths/types/operations.d.ts +188 -0
- package/dist/lib/maths/types/operations.d.ts.map +1 -0
- package/dist/lib/maths/types/operations.js +6 -0
- package/dist/lib/maths/types/operations.mjs +0 -0
- package/dist/lib/object/clone.cjs +1 -0
- package/dist/lib/object/clone.d.ts +46 -0
- package/dist/lib/object/clone.d.ts.map +1 -0
- package/dist/lib/object/clone.js +104 -0
- package/dist/lib/object/clone.mjs +1 -0
- package/dist/lib/object/diff.cjs +1 -0
- package/dist/lib/object/diff.d.ts +203 -0
- package/dist/lib/object/diff.d.ts.map +1 -0
- package/dist/lib/object/diff.js +805 -0
- package/dist/lib/object/diff.mjs +1 -0
- package/dist/lib/object/getter-setter.cjs +1 -0
- package/dist/lib/object/getter-setter.d.ts +361 -0
- package/dist/lib/object/getter-setter.d.ts.map +1 -0
- package/dist/lib/object/getter-setter.js +1771 -0
- package/dist/lib/object/getter-setter.mjs +1 -0
- package/dist/lib/object/index.cjs +6 -0
- package/dist/lib/object/index.d.ts +13 -0
- package/dist/lib/object/index.d.ts.map +1 -0
- package/dist/lib/object/index.js +12 -0
- package/dist/lib/object/index.mjs +6 -0
- package/dist/lib/object/merge.cjs +1 -0
- package/dist/lib/object/merge.d.ts +93 -0
- package/dist/lib/object/merge.d.ts.map +1 -0
- package/dist/lib/object/merge.js +474 -0
- package/dist/lib/object/merge.mjs +1 -0
- package/dist/lib/object/object.cjs +1 -0
- package/dist/lib/object/object.d.ts +128 -0
- package/dist/lib/object/object.d.ts.map +1 -0
- package/dist/lib/object/object.js +432 -0
- package/dist/lib/object/object.mjs +1 -0
- package/dist/lib/object/omit.cjs +1 -0
- package/dist/lib/object/omit.d.ts +351 -0
- package/dist/lib/object/omit.d.ts.map +1 -0
- package/dist/lib/object/omit.js +656 -0
- package/dist/lib/object/omit.mjs +1 -0
- package/dist/lib/object/reconcile.cjs +1 -0
- package/dist/lib/object/reconcile.d.ts +7 -0
- package/dist/lib/object/reconcile.d.ts.map +1 -0
- package/dist/lib/object/reconcile.js +122 -0
- package/dist/lib/object/reconcile.mjs +1 -0
- package/dist/lib/object/selector.cjs +1 -0
- package/dist/lib/object/selector.d.ts +50 -0
- package/dist/lib/object/selector.d.ts.map +1 -0
- package/dist/lib/object/selector.js +371 -0
- package/dist/lib/object/selector.mjs +1 -0
- package/dist/lib/object/sort.cjs +1 -0
- package/dist/lib/object/sort.d.ts +149 -0
- package/dist/lib/object/sort.d.ts.map +1 -0
- package/dist/lib/object/sort.js +298 -0
- package/dist/lib/object/sort.mjs +1 -0
- package/dist/lib/object/transform.cjs +1 -0
- package/dist/lib/object/transform.d.ts +620 -0
- package/dist/lib/object/transform.d.ts.map +1 -0
- package/dist/lib/object/transform.js +1058 -0
- package/dist/lib/object/transform.mjs +1 -0
- package/dist/lib/object/types.cjs +1 -0
- package/dist/lib/object/types.d.ts +250 -0
- package/dist/lib/object/types.d.ts.map +1 -0
- package/dist/lib/object/types.js +1 -0
- package/dist/lib/object/types.mjs +0 -0
- package/dist/lib/object/utils.cjs +6 -0
- package/dist/lib/object/utils.d.ts +165 -0
- package/dist/lib/object/utils.d.ts.map +1 -0
- package/dist/lib/object/utils.js +444 -0
- package/dist/lib/object/utils.mjs +6 -0
- package/dist/lib/primitive/boolean/boolean.cjs +1 -0
- package/dist/lib/primitive/boolean/boolean.d.ts +276 -0
- package/dist/lib/primitive/boolean/boolean.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/boolean.js +615 -0
- package/dist/lib/primitive/boolean/boolean.mjs +1 -0
- package/dist/lib/primitive/boolean/index.cjs +1 -0
- package/dist/lib/primitive/boolean/index.d.ts +3 -0
- package/dist/lib/primitive/boolean/index.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/index.js +2 -0
- package/dist/lib/primitive/boolean/index.mjs +1 -0
- package/dist/lib/primitive/boolean/types.cjs +1 -0
- package/dist/lib/primitive/boolean/types.d.ts +14 -0
- package/dist/lib/primitive/boolean/types.d.ts.map +1 -0
- package/dist/lib/primitive/boolean/types.js +1 -0
- package/dist/lib/primitive/boolean/types.mjs +0 -0
- package/dist/lib/primitive/date/date.cjs +1 -0
- package/dist/lib/primitive/date/date.d.ts +641 -0
- package/dist/lib/primitive/date/date.d.ts.map +1 -0
- package/dist/lib/primitive/date/date.js +1998 -0
- package/dist/lib/primitive/date/date.mjs +1 -0
- package/dist/lib/primitive/date/index.cjs +1 -0
- package/dist/lib/primitive/date/index.d.ts +3 -0
- package/dist/lib/primitive/date/index.d.ts.map +1 -0
- package/dist/lib/primitive/date/index.js +2 -0
- package/dist/lib/primitive/date/index.mjs +1 -0
- package/dist/lib/primitive/date/types.cjs +1 -0
- package/dist/lib/primitive/date/types.d.ts +205 -0
- package/dist/lib/primitive/date/types.d.ts.map +1 -0
- package/dist/lib/primitive/date/types.js +7 -0
- package/dist/lib/primitive/date/types.mjs +0 -0
- package/dist/lib/primitive/index.cjs +5 -0
- package/dist/lib/primitive/index.d.ts +5 -0
- package/dist/lib/primitive/index.d.ts.map +1 -0
- package/dist/lib/primitive/index.js +4 -0
- package/dist/lib/primitive/index.mjs +5 -0
- package/dist/lib/primitive/string/index.cjs +5 -0
- package/dist/lib/primitive/string/index.d.ts +3 -0
- package/dist/lib/primitive/string/index.d.ts.map +1 -0
- package/dist/lib/primitive/string/index.js +2 -0
- package/dist/lib/primitive/string/index.mjs +5 -0
- package/dist/lib/primitive/string/parser-2.cjs +8 -0
- package/dist/lib/primitive/string/parser-2.d.ts +17 -0
- package/dist/lib/primitive/string/parser-2.d.ts.map +1 -0
- package/dist/lib/primitive/string/parser-2.js +656 -0
- package/dist/lib/primitive/string/parser-2.mjs +8 -0
- package/dist/lib/primitive/string/parser.cjs +3 -0
- package/dist/lib/primitive/string/parser.d.ts +9 -0
- package/dist/lib/primitive/string/parser.d.ts.map +1 -0
- package/dist/lib/primitive/string/parser.js +775 -0
- package/dist/lib/primitive/string/parser.mjs +3 -0
- package/dist/lib/primitive/string/string.cjs +5 -0
- package/dist/lib/primitive/string/string.d.ts +535 -0
- package/dist/lib/primitive/string/string.d.ts.map +1 -0
- package/dist/lib/primitive/string/string.js +1301 -0
- package/dist/lib/primitive/string/string.mjs +5 -0
- package/dist/lib/primitive/string/types.cjs +1 -0
- package/dist/lib/primitive/string/types.d.ts +318 -0
- package/dist/lib/primitive/string/types.d.ts.map +1 -0
- package/dist/lib/primitive/string/types.js +5 -0
- package/dist/lib/primitive/string/types.mjs +0 -0
- package/dist/lib/primitive/types.cjs +1 -0
- package/dist/lib/primitive/types.d.ts +27 -0
- package/dist/lib/primitive/types.d.ts.map +1 -0
- package/dist/lib/primitive/types.js +1 -0
- package/dist/lib/primitive/types.mjs +0 -0
- package/dist/lib/url/index.cjs +1 -0
- package/dist/lib/url/index.d.ts +3 -0
- package/dist/lib/url/index.d.ts.map +1 -0
- package/dist/lib/url/index.js +2 -0
- package/dist/lib/url/index.mjs +1 -0
- package/dist/lib/url/parser.cjs +1 -0
- package/dist/lib/url/parser.d.ts +216 -0
- package/dist/lib/url/parser.d.ts.map +1 -0
- package/dist/lib/url/parser.js +488 -0
- package/dist/lib/url/parser.mjs +1 -0
- package/dist/lib/url/types.cjs +1 -0
- package/dist/lib/url/types.d.ts +18 -0
- package/dist/lib/url/types.d.ts.map +1 -0
- package/dist/lib/url/types.js +1 -0
- package/dist/lib/url/types.mjs +0 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +150 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { isObject } from './utils.js';
|
|
2
|
+
import { deletePath, get } from './getter-setter.js';
|
|
3
|
+
import { parseSelector } from './selector.js';
|
|
4
|
+
import { deepMerge } from './merge.js';
|
|
5
|
+
/**
|
|
6
|
+
* Omits specified properties from an object
|
|
7
|
+
*
|
|
8
|
+
* Creates a new object without the specified keys. This is a shallow operation -
|
|
9
|
+
* nested objects are copied by reference.
|
|
10
|
+
*
|
|
11
|
+
* @template T - The input object type
|
|
12
|
+
* @template K - The keys to omit from the object
|
|
13
|
+
* @param obj - The source object
|
|
14
|
+
* @param keys - The keys to omit
|
|
15
|
+
* @returns A new object without the omitted keys
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const user = { id: 1, name: 'Alice', password: 'secret' };
|
|
20
|
+
* const safeUser = omit(user, ['password']);
|
|
21
|
+
* // { id: 1, name: 'Alice' }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const config = { server: 'localhost', port: 8080, timeout: 5000, retries: 3 };
|
|
27
|
+
* const essentialConfig = omit(config, ['timeout', 'retries']);
|
|
28
|
+
* // { server: 'localhost', port: 8080 }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function omit(obj, keys) {
|
|
32
|
+
if (!isObject(obj)) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
const result = { ...obj };
|
|
36
|
+
for (const key of keys) {
|
|
37
|
+
delete result[key];
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Deeply omits specified properties at any level of an object or array
|
|
43
|
+
*
|
|
44
|
+
* Recursively removes the specified keys from an object and all nested objects.
|
|
45
|
+
* Creates a new deep copy of the object with the keys removed at every level.
|
|
46
|
+
*
|
|
47
|
+
* @template T - The input object type
|
|
48
|
+
* @param obj - The source object or array
|
|
49
|
+
* @param keys - Keys to omit at any level
|
|
50
|
+
* @returns A new deep copy with the keys omitted at every level
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const user = {
|
|
55
|
+
* id: 1,
|
|
56
|
+
* name: 'Alice',
|
|
57
|
+
* meta: {
|
|
58
|
+
* password: 'secret',
|
|
59
|
+
* tokens: {
|
|
60
|
+
* refresh: 'abc',
|
|
61
|
+
* password: '123'
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* };
|
|
65
|
+
*
|
|
66
|
+
* const safeUser = deepOmit(user, ['password']);
|
|
67
|
+
* // {
|
|
68
|
+
* // id: 1,
|
|
69
|
+
* // name: 'Alice',
|
|
70
|
+
* // meta: {
|
|
71
|
+
* // tokens: {
|
|
72
|
+
* // refresh: 'abc'
|
|
73
|
+
* // }
|
|
74
|
+
* // }
|
|
75
|
+
* // }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export function deepOmit(obj, keys) {
|
|
79
|
+
if (obj === null || obj === undefined || typeof obj !== 'object') {
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(obj)) {
|
|
83
|
+
return obj.map((item) => deepOmit(item, keys));
|
|
84
|
+
}
|
|
85
|
+
const result = {};
|
|
86
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
87
|
+
if (!keys.includes(key)) {
|
|
88
|
+
result[key] = deepOmit(value, keys);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a function that omits specific properties from objects
|
|
95
|
+
*
|
|
96
|
+
* Returns a reusable function that will omit the specified keys from any object passed to it.
|
|
97
|
+
* This is useful when you need to omit the same keys from multiple objects.
|
|
98
|
+
*
|
|
99
|
+
* @template K - The keys to omit
|
|
100
|
+
* @param keys - The keys to omit from objects
|
|
101
|
+
* @returns A function that omits the specified keys from objects
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* const removeSensitiveData = createOmitter(['password', 'ssn', 'creditCard']);
|
|
106
|
+
*
|
|
107
|
+
* const user1 = { id: 1, name: 'Alice', password: 'secret', ssn: '123-45-6789' };
|
|
108
|
+
* const user2 = { id: 2, name: 'Bob', password: 'p@ssword', creditCard: '4111-1111-1111-1111' };
|
|
109
|
+
*
|
|
110
|
+
* const safeUser1 = removeSensitiveData(user1);
|
|
111
|
+
* // { id: 1, name: 'Alice' }
|
|
112
|
+
*
|
|
113
|
+
* const safeUser2 = removeSensitiveData(user2);
|
|
114
|
+
* // { id: 2, name: 'Bob' }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export function createOmitter(keys) {
|
|
118
|
+
return (obj) => {
|
|
119
|
+
if (!isObject(obj)) {
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
122
|
+
const result = { ...obj };
|
|
123
|
+
for (const key of keys) {
|
|
124
|
+
if (key in result) {
|
|
125
|
+
delete result[key];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Omits keys from an object based on a predicate function
|
|
133
|
+
*
|
|
134
|
+
* Creates a new object excluding properties for which the predicate returns true.
|
|
135
|
+
* The predicate is called with each property's value, key, and the original object.
|
|
136
|
+
*
|
|
137
|
+
* @template T - The input object type
|
|
138
|
+
* @param obj - The source object
|
|
139
|
+
* @param predicate - Function to test each property
|
|
140
|
+
* @returns A new object with filtered properties
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const data = { a: 1, b: null, c: 3, d: undefined, e: 5 };
|
|
145
|
+
*
|
|
146
|
+
* // Remove null and undefined values
|
|
147
|
+
* const cleaned = omitBy(data, value => value == null);
|
|
148
|
+
* // { a: 1, c: 3, e: 5 }
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const user = { name: 'Alice', admin: true, lastLogin: Date.now() };
|
|
154
|
+
*
|
|
155
|
+
* // Remove boolean properties
|
|
156
|
+
* const withoutBooleans = omitBy(user, value => typeof value === 'boolean');
|
|
157
|
+
* // { name: 'Alice', lastLogin: 1636271340081 }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export function omitBy(obj, predicate) {
|
|
161
|
+
if (!isObject(obj)) {
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
164
|
+
const result = {};
|
|
165
|
+
for (const key in obj) {
|
|
166
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) &&
|
|
167
|
+
!predicate(obj[key], key, obj)) {
|
|
168
|
+
result[key] = obj[key];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Removes null and undefined values from an object
|
|
175
|
+
*
|
|
176
|
+
* Creates a new object excluding properties that have null or undefined values.
|
|
177
|
+
* This is a common use case for cleaning up objects before serialization or API requests.
|
|
178
|
+
*
|
|
179
|
+
* @template T - The input object type
|
|
180
|
+
* @param obj - The source object
|
|
181
|
+
* @returns A new object without null or undefined properties
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const data = {
|
|
186
|
+
* name: 'Alice',
|
|
187
|
+
* age: 30,
|
|
188
|
+
* address: null,
|
|
189
|
+
* phone: undefined,
|
|
190
|
+
* email: 'alice@example.com'
|
|
191
|
+
* };
|
|
192
|
+
*
|
|
193
|
+
* const cleaned = omitNil(data);
|
|
194
|
+
* // { name: 'Alice', age: 30, email: 'alice@example.com' }
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function omitNil(obj) {
|
|
198
|
+
return omitBy(obj, (value) => value === null || value === undefined);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Extracts a subset of properties from an object
|
|
202
|
+
*
|
|
203
|
+
* Creates a new object with only the specified keys.
|
|
204
|
+
* This is the opposite of omit - instead of saying what to exclude, you specify what to include.
|
|
205
|
+
*
|
|
206
|
+
* @template T - The input object type
|
|
207
|
+
* @template K - The keys to pick from the object
|
|
208
|
+
* @param obj - The source object
|
|
209
|
+
* @param keys - The keys to include in the result
|
|
210
|
+
* @returns A new object with only the picked keys
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* const user = { id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin' };
|
|
215
|
+
*
|
|
216
|
+
* const credentials = pick(user, ['name', 'email']);
|
|
217
|
+
* // { name: 'Alice', email: 'alice@example.com' }
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export function pick(obj, keys) {
|
|
221
|
+
if (!isObject(obj)) {
|
|
222
|
+
return {};
|
|
223
|
+
}
|
|
224
|
+
const result = {};
|
|
225
|
+
for (const key of keys) {
|
|
226
|
+
if (key in obj) {
|
|
227
|
+
result[key] = obj[key];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Extracts properties from an object based on a predicate function
|
|
234
|
+
*
|
|
235
|
+
* Creates a new object with only the properties for which the predicate returns true.
|
|
236
|
+
* The predicate is called with each property's value, key, and the original object.
|
|
237
|
+
*
|
|
238
|
+
* @template T - The input object type
|
|
239
|
+
* @param obj - The source object
|
|
240
|
+
* @param predicate - Function to test each property
|
|
241
|
+
* @returns A new object with only the properties that pass the predicate
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* const data = { a: 1, b: 2, c: 3, d: 4, e: 5 };
|
|
246
|
+
*
|
|
247
|
+
* // Keep only even numbers
|
|
248
|
+
* const evens = pickBy(data, value => value % 2 === 0);
|
|
249
|
+
* // { b: 2, d: 4 }
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* const user = { name: 'Alice', age: 30, admin: true, banned: false };
|
|
255
|
+
*
|
|
256
|
+
* // Keep only boolean properties
|
|
257
|
+
* const flags = pickBy(user, value => typeof value === 'boolean');
|
|
258
|
+
* // { admin: true, banned: false }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export function pickBy(obj, predicate) {
|
|
262
|
+
if (!isObject(obj)) {
|
|
263
|
+
return {};
|
|
264
|
+
}
|
|
265
|
+
const result = {};
|
|
266
|
+
for (const key in obj) {
|
|
267
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) &&
|
|
268
|
+
predicate(obj[key], key, obj)) {
|
|
269
|
+
result[key] = obj[key];
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Omits properties from an object based on path selectors with optional transformation
|
|
276
|
+
*
|
|
277
|
+
* Creates a new object excluding properties at the specified path(s). Supports
|
|
278
|
+
* advanced path selectors including property paths, array indices, wildcards, and filters.
|
|
279
|
+
* Optionally accepts a transformation function for more granular control.
|
|
280
|
+
*
|
|
281
|
+
* @template T - The input object type
|
|
282
|
+
* @param obj - The source object
|
|
283
|
+
* @param paths - Path selector or array of path selectors to the properties to omit
|
|
284
|
+
* @param transform - Optional function to control or transform properties
|
|
285
|
+
* @returns A new object with properties omitted or transformed
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* const user = {
|
|
290
|
+
* id: 1,
|
|
291
|
+
* name: 'Alice',
|
|
292
|
+
* profile: {
|
|
293
|
+
* email: 'alice@example.com',
|
|
294
|
+
* password: 'secret',
|
|
295
|
+
* settings: {
|
|
296
|
+
* theme: 'dark',
|
|
297
|
+
* notifications: true
|
|
298
|
+
* }
|
|
299
|
+
* }
|
|
300
|
+
* };
|
|
301
|
+
*
|
|
302
|
+
* // Omit nested property
|
|
303
|
+
* const safeUser = omitPath(user, 'profile.password');
|
|
304
|
+
* // Result: user object without the password field
|
|
305
|
+
*
|
|
306
|
+
* // Omit multiple paths
|
|
307
|
+
* const publicUser = omitPath(user, ['profile.password', 'profile.email']);
|
|
308
|
+
* // Result: user object without password and email fields
|
|
309
|
+
*
|
|
310
|
+
* // Omit with wildcard
|
|
311
|
+
* const data = {
|
|
312
|
+
* users: [
|
|
313
|
+
* { id: 1, name: 'Alice', password: 'secret1' },
|
|
314
|
+
* { id: 2, name: 'Bob', password: 'secret2' }
|
|
315
|
+
* ]
|
|
316
|
+
* };
|
|
317
|
+
* const safeData = omitPath(data, 'users[*].password');
|
|
318
|
+
* // Result: data with password removed from all users
|
|
319
|
+
*
|
|
320
|
+
* // With transformation function
|
|
321
|
+
* const transformedUser = omitPath(user, 'profile.email', (value, path) => {
|
|
322
|
+
* // Return true to omit the property
|
|
323
|
+
* // Return false to keep the property intact
|
|
324
|
+
* // Return a value to transform the property
|
|
325
|
+
* if (path === 'profile.email') {
|
|
326
|
+
* return value.split('@')[0] + '@example.org'; // Transform email
|
|
327
|
+
* }
|
|
328
|
+
* return false; // Keep other properties
|
|
329
|
+
* });
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
export function omitPath(obj, paths, transform) {
|
|
333
|
+
if (!isObject(obj)) {
|
|
334
|
+
// return obj;
|
|
335
|
+
return {};
|
|
336
|
+
}
|
|
337
|
+
// Make a deep clone to avoid modifying original
|
|
338
|
+
const result = JSON.parse(JSON.stringify(obj));
|
|
339
|
+
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
340
|
+
// Process each path
|
|
341
|
+
for (let i = 0; i < pathArray.length; i++) {
|
|
342
|
+
const path = pathArray[i];
|
|
343
|
+
const nextPath = pathArray[i + 1];
|
|
344
|
+
if (!path || path === '')
|
|
345
|
+
continue;
|
|
346
|
+
const segments = parseSelector(path);
|
|
347
|
+
// Handle wildcards and complex paths
|
|
348
|
+
if (path.includes('*') || path.includes('[') || segments.length > 1) {
|
|
349
|
+
// Get all matching paths
|
|
350
|
+
const value = get(result, path, { preserveStructure: true });
|
|
351
|
+
if (value === undefined) {
|
|
352
|
+
continue; // Path doesn't exist, continue to next path
|
|
353
|
+
}
|
|
354
|
+
// For each matching path, remove or transform the property
|
|
355
|
+
const pathsToProcess = [];
|
|
356
|
+
// Collect all paths to process
|
|
357
|
+
function collectPaths(obj, currentPath = '') {
|
|
358
|
+
if (!isObject(obj))
|
|
359
|
+
return;
|
|
360
|
+
if (Array.isArray(obj)) {
|
|
361
|
+
obj.forEach((item, index) => {
|
|
362
|
+
collectPaths(item, currentPath ? `${currentPath}[${index}]` : `[${index}]`);
|
|
363
|
+
});
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
for (const key in obj) {
|
|
367
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
368
|
+
const fullPath = currentPath ? `${currentPath}.${key}` : key;
|
|
369
|
+
pathsToProcess.push({
|
|
370
|
+
fullPath,
|
|
371
|
+
segments: parseSelector(fullPath),
|
|
372
|
+
});
|
|
373
|
+
collectPaths(obj[key], fullPath);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
collectPaths(value);
|
|
378
|
+
// Process each path
|
|
379
|
+
for (const { fullPath, segments: pathSegments } of pathsToProcess) {
|
|
380
|
+
const pathSegmentsCopy = [...pathSegments];
|
|
381
|
+
const lastSegment = pathSegmentsCopy.pop();
|
|
382
|
+
if (!lastSegment)
|
|
383
|
+
continue;
|
|
384
|
+
const parentPath = pathSegmentsCopy
|
|
385
|
+
.map((s) => {
|
|
386
|
+
if (s.type === 'index')
|
|
387
|
+
return `[${s.value}]`;
|
|
388
|
+
return s.value;
|
|
389
|
+
})
|
|
390
|
+
.join('.')
|
|
391
|
+
.replace(/\.\[/g, '[');
|
|
392
|
+
const fg = get(result, parentPath.length > 0 ? parentPath : fullPath, {
|
|
393
|
+
preserveStructure: true,
|
|
394
|
+
});
|
|
395
|
+
let parent = parentPath ? fg : result;
|
|
396
|
+
// Check if parent exists and is an object
|
|
397
|
+
if (!parent) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const propertyKey = String(lastSegment.value);
|
|
401
|
+
const currentValue = parent[propertyKey];
|
|
402
|
+
if (transform) {
|
|
403
|
+
// Apply transform function if provided
|
|
404
|
+
const transformResult = transform(currentValue, fullPath, result);
|
|
405
|
+
if (transformResult === true) {
|
|
406
|
+
// Remove property if transform returns true
|
|
407
|
+
if (lastSegment.type === 'index' && Array.isArray(parent)) {
|
|
408
|
+
const index = lastSegment.value;
|
|
409
|
+
if (index >= 0 && index < parent.length) {
|
|
410
|
+
parent.splice(index, 1);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
// delete parent[propertyKey];
|
|
415
|
+
deletePath(result, pathArray[i]);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else if (transformResult !== false) {
|
|
419
|
+
// Update with transformed value if not false
|
|
420
|
+
parent[propertyKey] = transformResult;
|
|
421
|
+
}
|
|
422
|
+
// If false, keep property as is
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
// Default behavior: remove property
|
|
426
|
+
if (lastSegment.type === 'index' && Array.isArray(parent)) {
|
|
427
|
+
const index = lastSegment.value;
|
|
428
|
+
if (index >= 0 && index < parent.length) {
|
|
429
|
+
parent.splice(index, 1);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
// delete parent[propertyKey];
|
|
434
|
+
deletePath(result, pathArray[i]);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
// Simple case - direct property
|
|
441
|
+
const key = path;
|
|
442
|
+
if (typeof key === 'string' && key in result) {
|
|
443
|
+
if (transform) {
|
|
444
|
+
// Apply transform function if provided
|
|
445
|
+
const transformResult = transform(result[key], path, result);
|
|
446
|
+
if (transformResult === true) {
|
|
447
|
+
// Remove property if transform returns true
|
|
448
|
+
delete result[key];
|
|
449
|
+
}
|
|
450
|
+
else if (transformResult !== false) {
|
|
451
|
+
// Update with transformed value if not false
|
|
452
|
+
result[key] = transformResult;
|
|
453
|
+
}
|
|
454
|
+
// If false, keep property as is
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
// Default behavior: remove property
|
|
458
|
+
// delete result[key];
|
|
459
|
+
deletePath(result, pathArray[i]);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Picks properties from an object based on a path selector
|
|
468
|
+
*
|
|
469
|
+
* Creates a new object with only the properties at the specified path. Supports
|
|
470
|
+
* advanced path selectors including property paths, array indices, wildcards, and filters.
|
|
471
|
+
*
|
|
472
|
+
* @template T - The input object type
|
|
473
|
+
* @param obj - The source object
|
|
474
|
+
* @param paths - Path selector or array of path selectors to the properties to pick
|
|
475
|
+
* @param transform - Optional function to transform picked properties
|
|
476
|
+
* @returns A new object with only the properties at the specified path
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```ts
|
|
480
|
+
* const user = {
|
|
481
|
+
* id: 1,
|
|
482
|
+
* name: 'Alice',
|
|
483
|
+
* profile: {
|
|
484
|
+
* email: 'alice@example.com',
|
|
485
|
+
* settings: {
|
|
486
|
+
* theme: 'dark',
|
|
487
|
+
* notifications: true
|
|
488
|
+
* }
|
|
489
|
+
* },
|
|
490
|
+
* posts: [
|
|
491
|
+
* { id: 101, title: 'Hello', content: 'World' },
|
|
492
|
+
* { id: 102, title: 'Foo', content: 'Bar' }
|
|
493
|
+
* ]
|
|
494
|
+
* };
|
|
495
|
+
*
|
|
496
|
+
* // Pick nested property
|
|
497
|
+
* const userEmail = pickPath(user, 'profile.email');
|
|
498
|
+
* // Result: { profile: { email: 'alice@example.com' } }
|
|
499
|
+
*
|
|
500
|
+
* // Pick multiple paths
|
|
501
|
+
* const basicInfo = pickPath(user, ['id', 'name', 'profile.email']);
|
|
502
|
+
* // Result: { id: 1, name: 'Alice', profile: { email: 'alice@example.com' } }
|
|
503
|
+
*
|
|
504
|
+
* // Pick with wildcard
|
|
505
|
+
* const postTitles = pickPath(user, 'posts[*].title');
|
|
506
|
+
* // Result: { posts: [{ title: 'Hello' }, { title: 'Foo' }] }
|
|
507
|
+
*
|
|
508
|
+
* // With transformation function
|
|
509
|
+
* const transformed = pickPath(user, ['name', 'profile.email'], (value, path) => {
|
|
510
|
+
* if (path === 'name') {
|
|
511
|
+
* return value.toUpperCase();
|
|
512
|
+
* }
|
|
513
|
+
* if (path === 'profile.email') {
|
|
514
|
+
* return value.split('@')[0] + '@example.org';
|
|
515
|
+
* }
|
|
516
|
+
* return value;
|
|
517
|
+
* });
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
export function pickPath(obj, paths, transform) {
|
|
521
|
+
if (!isObject(obj)) {
|
|
522
|
+
return {};
|
|
523
|
+
}
|
|
524
|
+
// Handle array of paths
|
|
525
|
+
if (Array.isArray(paths)) {
|
|
526
|
+
// Create a merged result from all paths
|
|
527
|
+
const result = {};
|
|
528
|
+
for (const path of paths) {
|
|
529
|
+
const pathValue = get(obj, path, { preserveStructure: true });
|
|
530
|
+
if (pathValue === undefined) {
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
if (transform) {
|
|
534
|
+
// Apply transformation to the leaf values
|
|
535
|
+
const transformValue = (value, currentPath) => {
|
|
536
|
+
if (isObject(value)) {
|
|
537
|
+
if (Array.isArray(value)) {
|
|
538
|
+
return value.map((item, index) => transformValue(item, `${currentPath}[${index}]`));
|
|
539
|
+
}
|
|
540
|
+
const result = {};
|
|
541
|
+
for (const key in value) {
|
|
542
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
543
|
+
const nestedPath = currentPath ? `${currentPath}.${key}` : key;
|
|
544
|
+
result[key] = transformValue(value[key], nestedPath);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return result;
|
|
548
|
+
}
|
|
549
|
+
return transform(value, currentPath, obj);
|
|
550
|
+
};
|
|
551
|
+
const transformedValue = transformValue(pathValue, path);
|
|
552
|
+
// Merge into the result
|
|
553
|
+
deepMerge(result, transformedValue);
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
// Merge without transformation
|
|
557
|
+
Object.assign(result, deepMerge(result, pathValue));
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return result;
|
|
561
|
+
}
|
|
562
|
+
// Single path processing
|
|
563
|
+
const pathString = Array.isArray(paths) ? paths[0] : paths;
|
|
564
|
+
const value = get(obj, pathString, { preserveStructure: true });
|
|
565
|
+
if (value === undefined) {
|
|
566
|
+
return {};
|
|
567
|
+
}
|
|
568
|
+
if (transform) {
|
|
569
|
+
// Apply transformation to the leaf values
|
|
570
|
+
const transformValue = (value, currentPath) => {
|
|
571
|
+
if (isObject(value)) {
|
|
572
|
+
if (Array.isArray(value)) {
|
|
573
|
+
return value.map((item, index) => transformValue(item, `${currentPath}[${index}]`));
|
|
574
|
+
}
|
|
575
|
+
const result = {};
|
|
576
|
+
for (const key in value) {
|
|
577
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
578
|
+
const nestedPath = currentPath ? `${currentPath}.${key}` : key;
|
|
579
|
+
result[key] = transformValue(value[key], nestedPath);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return result;
|
|
583
|
+
}
|
|
584
|
+
return transform(value, currentPath, obj);
|
|
585
|
+
};
|
|
586
|
+
return transformValue(value, pathString);
|
|
587
|
+
}
|
|
588
|
+
return value;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Deeply omits properties matching a predicate at all levels of an object
|
|
592
|
+
*
|
|
593
|
+
* Recursively traverses an object and omits properties for which the predicate returns true.
|
|
594
|
+
* This applies at every level of the object, not just the top level.
|
|
595
|
+
*
|
|
596
|
+
* @template T - The input object type
|
|
597
|
+
* @param obj - The source object
|
|
598
|
+
* @param predicate - Function to test each property
|
|
599
|
+
* @returns A new object with properties omitted at all levels
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```ts
|
|
603
|
+
* const data = {
|
|
604
|
+
* id: 1,
|
|
605
|
+
* name: 'Alice',
|
|
606
|
+
* password: 'secret',
|
|
607
|
+
* profile: {
|
|
608
|
+
* email: 'alice@example.com',
|
|
609
|
+
* password: 'another-secret',
|
|
610
|
+
* settings: {
|
|
611
|
+
* token: 'abc123',
|
|
612
|
+
* theme: 'dark'
|
|
613
|
+
* }
|
|
614
|
+
* },
|
|
615
|
+
* posts: [
|
|
616
|
+
* { id: 101, private: true, content: 'Hello' },
|
|
617
|
+
* { id: 102, private: false, content: 'World' }
|
|
618
|
+
* ]
|
|
619
|
+
* };
|
|
620
|
+
*
|
|
621
|
+
* // Omit all sensitive fields
|
|
622
|
+
* const sanitized = deepOmitBy(data, (value, key) =>
|
|
623
|
+
* ['password', 'token', 'private'].includes(key)
|
|
624
|
+
* );
|
|
625
|
+
* // Result: Object with password, token and private fields removed at all levels
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
export function deepOmitBy(obj, predicate) {
|
|
629
|
+
if (!isObject(obj)) {
|
|
630
|
+
return obj;
|
|
631
|
+
}
|
|
632
|
+
if (Array.isArray(obj)) {
|
|
633
|
+
return obj.map((item) => deepOmitBy(item, predicate));
|
|
634
|
+
}
|
|
635
|
+
const result = {};
|
|
636
|
+
for (const key in obj) {
|
|
637
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
const value = obj[key];
|
|
641
|
+
if (predicate(value, key, obj)) {
|
|
642
|
+
continue; // Skip this property
|
|
643
|
+
}
|
|
644
|
+
// Recursively process object and array values
|
|
645
|
+
if (isObject(value)) {
|
|
646
|
+
result[key] = deepOmitBy(value, predicate);
|
|
647
|
+
}
|
|
648
|
+
else if (Array.isArray(value)) {
|
|
649
|
+
result[key] = value.map((item) => deepOmitBy(item, predicate));
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
result[key] = value;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return result;
|
|
656
|
+
}
|