@magic/deep 0.1.16 → 0.1.18
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 +16 -7
- package/package.json +13 -7
- package/src/flatten.js +33 -0
- package/src/{index.mjs → index.js} +3 -3
- package/src/loop.js +94 -0
- package/src/{merge.mjs → merge.js} +14 -5
- package/types/flatten.d.ts +4 -0
- package/types/index.d.ts +34 -0
- package/types/loop.d.ts +2 -0
- package/types/merge.d.ts +2 -0
- package/src/flatten.mjs +0 -9
- package/src/loop.mjs +0 -35
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ deep.equal(['shallow', ['deep']], ['shallow', ['deep']])
|
|
|
48
48
|
// true
|
|
49
49
|
|
|
50
50
|
// alias
|
|
51
|
-
deep.equals, deep.eq
|
|
51
|
+
// deep.equals, deep.eq
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
##### deep.different
|
|
@@ -59,7 +59,7 @@ deep.different(['shallow', ['deep']], ['shallow', ['deep']])
|
|
|
59
59
|
// false
|
|
60
60
|
|
|
61
61
|
// alias
|
|
62
|
-
deep.diff
|
|
62
|
+
// deep.diff
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
##### deep.flatten
|
|
@@ -159,22 +159,31 @@ update dependencies
|
|
|
159
159
|
|
|
160
160
|
update dependencies
|
|
161
161
|
|
|
162
|
-
##### 0.
|
|
162
|
+
##### 0.1.13
|
|
163
163
|
|
|
164
164
|
update dependencies
|
|
165
165
|
|
|
166
|
-
##### 0.
|
|
166
|
+
##### 0.1.14
|
|
167
167
|
|
|
168
168
|
update dependencies
|
|
169
169
|
|
|
170
|
-
##### 0.
|
|
170
|
+
##### 0.1.15
|
|
171
171
|
|
|
172
172
|
update dependencies
|
|
173
173
|
|
|
174
|
-
##### 0.
|
|
174
|
+
##### 0.1.16
|
|
175
175
|
|
|
176
176
|
update dependencies
|
|
177
177
|
|
|
178
|
-
##### 0.
|
|
178
|
+
##### 0.1.17
|
|
179
|
+
|
|
180
|
+
- add typescript types
|
|
181
|
+
- update dependencies
|
|
182
|
+
|
|
183
|
+
##### 0.1.18
|
|
184
|
+
|
|
185
|
+
- actually add types to pkg files array
|
|
186
|
+
|
|
187
|
+
##### 0.0.19 - unreleased
|
|
179
188
|
|
|
180
189
|
...
|
package/package.json
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic/deep",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"author": "Wizards & Witches",
|
|
5
5
|
"description": "manipulate nested objects and arrays",
|
|
6
6
|
"homepage": "https://github.com/magic/deep",
|
|
7
7
|
"license": "AGPL-3.0",
|
|
8
|
-
"main": "src/index.
|
|
9
|
-
"
|
|
8
|
+
"main": "src/index.js",
|
|
9
|
+
"types": "types/index.d.ts",
|
|
10
|
+
"module": "src/index.js",
|
|
10
11
|
"type": "module",
|
|
11
12
|
"scripts": {
|
|
12
13
|
"start": "t",
|
|
14
|
+
"build": "tsc && npm run format",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
13
16
|
"test": "t",
|
|
14
17
|
"format": "f -w",
|
|
15
18
|
"format:check": "f",
|
|
@@ -27,14 +30,17 @@
|
|
|
27
30
|
"url": "https://github.com/magic/deep/issues"
|
|
28
31
|
},
|
|
29
32
|
"files": [
|
|
30
|
-
"src"
|
|
33
|
+
"src",
|
|
34
|
+
"types"
|
|
31
35
|
],
|
|
32
36
|
"dependencies": {
|
|
33
|
-
"@magic/types": "0.1.
|
|
37
|
+
"@magic/types": "0.1.26"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"@magic/format": "0.0.
|
|
37
|
-
"@magic/test": "0.2.
|
|
40
|
+
"@magic/format": "0.0.68",
|
|
41
|
+
"@magic/test": "0.2.20",
|
|
42
|
+
"@types/node": "24.5.2",
|
|
43
|
+
"typescript": "5.9.2"
|
|
38
44
|
},
|
|
39
45
|
"contributors": [
|
|
40
46
|
{
|
package/src/flatten.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import is from '@magic/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Flattens one level of an array if input is an array, otherwise returns the input as-is.
|
|
5
|
+
*
|
|
6
|
+
* @template T
|
|
7
|
+
* @param {T | T[]} flat - An array or value to flatten.
|
|
8
|
+
* @returns {T[]} The flattened value or array.
|
|
9
|
+
*/
|
|
10
|
+
export const shallow = flat => (is.array(flat) ? flatten(...flat) : [flat])
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Concatenates a flat array with another deep value or array.
|
|
14
|
+
*
|
|
15
|
+
* @template T
|
|
16
|
+
* @param {T[]} flat - The flat array to concatenate into.
|
|
17
|
+
* @param {T | T[]} deep - A value or array to be flattened and concatenated.
|
|
18
|
+
* @returns {T[]} The concatenated array.
|
|
19
|
+
*/
|
|
20
|
+
export const concat = (flat, deep) => flat.concat(shallow(deep))
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Recursively flattens one or more arrays into a single-level array.
|
|
24
|
+
*
|
|
25
|
+
* @template T
|
|
26
|
+
* @param {...(T | T[])} arr - The arrays or values to flatten.
|
|
27
|
+
* @returns {T[]} The flattened array.
|
|
28
|
+
*/
|
|
29
|
+
export const flatten = (...arr) =>
|
|
30
|
+
/** @type {T[]} */ (arr.reduce(/** @type {any} */ (concat), /** @type {T[]} */ ([])))
|
|
31
|
+
|
|
32
|
+
/** @type {(arr: any[]) => any[]} */
|
|
33
|
+
export default flatten
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import is from '@magic/types'
|
|
2
2
|
|
|
3
|
-
import { loop as lo } from './loop.
|
|
4
|
-
import { merge as me } from './merge.
|
|
5
|
-
import { flatten as fl } from './flatten.
|
|
3
|
+
import { loop as lo } from './loop.js'
|
|
4
|
+
import { merge as me } from './merge.js'
|
|
5
|
+
import { flatten as fl } from './flatten.js'
|
|
6
6
|
|
|
7
7
|
export const equal = is.deep.equal
|
|
8
8
|
export const equals = is.deep.equal
|
package/src/loop.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import is from '@magic/types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Recursively applies a function to items or transforms items based on conditions.
|
|
5
|
+
*
|
|
6
|
+
* @template T, R
|
|
7
|
+
* @param {((item: T) => R) | T} fn - Function to apply or the first item.
|
|
8
|
+
* @param {...any} items - Items to loop over (can be nested arrays).
|
|
9
|
+
* @returns {any} The transformed result, array of results, or undefined.
|
|
10
|
+
*/
|
|
11
|
+
export const loop = (fn, ...items) => {
|
|
12
|
+
// If no arguments, return undefined
|
|
13
|
+
if (!fn && items.length === 0) {
|
|
14
|
+
return undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// If only function provided, return undefined
|
|
18
|
+
if (is.function(fn) && items.length === 0) {
|
|
19
|
+
return undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let targets = items
|
|
23
|
+
|
|
24
|
+
// Check for argument swapping: if fn is not a function but we have items and one of them is a function
|
|
25
|
+
if (!is.function(fn) && items.length > 0) {
|
|
26
|
+
const functionIndex = items.findIndex(item => is.function(item))
|
|
27
|
+
if (functionIndex !== -1) {
|
|
28
|
+
// Swap: fn becomes the target, and the function becomes fn
|
|
29
|
+
const actualFn = items[functionIndex]
|
|
30
|
+
targets = [fn, ...items.slice(0, functionIndex), ...items.slice(functionIndex + 1)]
|
|
31
|
+
fn = actualFn
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Handle the case where we have multiple items but one of them is an object (options)
|
|
36
|
+
if (is.array(targets) && targets.length > 1) {
|
|
37
|
+
// Check if any item is an object (options pattern)
|
|
38
|
+
const hasOptions = targets.some(item => is.object(item) && !is.array(item))
|
|
39
|
+
|
|
40
|
+
if (hasOptions && is.function(fn)) {
|
|
41
|
+
// Apply function to each item
|
|
42
|
+
return targets.map(item => {
|
|
43
|
+
if (is.array(item)) {
|
|
44
|
+
return item.map(subItem => loop(fn, subItem))
|
|
45
|
+
}
|
|
46
|
+
return is.object(item) && !is.array(item)
|
|
47
|
+
? item
|
|
48
|
+
: /** @type {(item: any) => any} */ (fn)(item)
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!is.function(fn)) {
|
|
53
|
+
return [fn, ...targets]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Apply function to multiple items
|
|
57
|
+
return targets.map(item => {
|
|
58
|
+
if (is.array(item)) {
|
|
59
|
+
return item.map(subItem => loop(fn, subItem))
|
|
60
|
+
}
|
|
61
|
+
return /** @type {(item: any) => any} */ (fn)(item)
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Single item case - if targets is an array with one element, unwrap it
|
|
66
|
+
if (is.array(targets) && targets.length === 1) {
|
|
67
|
+
targets = /** @type {any} */ (targets[0])
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// If fn is not a function, return tuple
|
|
71
|
+
if (!is.function(fn)) {
|
|
72
|
+
return [fn, targets]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// If targets is null/undefined, apply function directly
|
|
76
|
+
if (!targets) {
|
|
77
|
+
return fn(targets)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// If targets has map method (is array-like), map over it
|
|
81
|
+
if (is.array(targets)) {
|
|
82
|
+
return targets.map(item => {
|
|
83
|
+
if (is.array(item)) {
|
|
84
|
+
return loop(fn, item)
|
|
85
|
+
}
|
|
86
|
+
return /** @type {(item: any) => any} */ (fn)(item)
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// For non-array targets, apply function directly
|
|
91
|
+
return /** @type {(item: any) => any} */ (fn)(targets)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default loop
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import is from '@magic/types'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Recursively merges two values or objects.
|
|
5
|
+
*
|
|
6
|
+
* @template T
|
|
7
|
+
* @template U
|
|
8
|
+
* @param {T} o1 - First value or object.
|
|
9
|
+
* @param {U} o2 - Second value or object.
|
|
10
|
+
* @returns {any} Merged result.
|
|
11
|
+
*/
|
|
3
12
|
export const merge = (o1, o2) => {
|
|
4
13
|
if (is.undefined(o1)) {
|
|
5
14
|
return o2
|
|
@@ -8,15 +17,16 @@ export const merge = (o1, o2) => {
|
|
|
8
17
|
}
|
|
9
18
|
|
|
10
19
|
if (is.array(o1)) {
|
|
11
|
-
return
|
|
20
|
+
return is.array(o2)
|
|
21
|
+
? /** @type {any[]} */ (o1).concat(/** @type {any[]} */ (o2))
|
|
22
|
+
: /** @type {any[]} */ (o1).concat([o2])
|
|
12
23
|
} else if (is.array(o2)) {
|
|
13
|
-
return [].concat(
|
|
24
|
+
return [o1].concat(/** @type {any[]} */ (o2))
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
if (is.mergeable(o1) && is.mergeable(o2)) {
|
|
17
28
|
const keys = Object.keys({ ...o1, ...o2 })
|
|
18
|
-
const final = {}
|
|
19
|
-
|
|
29
|
+
const final = /** @type {Record<string, any>} */ ({})
|
|
20
30
|
keys.forEach(key => {
|
|
21
31
|
if (!is.function(o2.hasOwnProperty) || !o2.hasOwnProperty(key)) {
|
|
22
32
|
final[key] = o1[key]
|
|
@@ -24,7 +34,6 @@ export const merge = (o1, o2) => {
|
|
|
24
34
|
final[key] = merge(o1[key], o2[key])
|
|
25
35
|
}
|
|
26
36
|
})
|
|
27
|
-
|
|
28
37
|
return final
|
|
29
38
|
}
|
|
30
39
|
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const equal: {
|
|
2
|
+
(a: unknown, b: unknown): boolean
|
|
3
|
+
(a: unknown): (c: unknown) => boolean
|
|
4
|
+
}
|
|
5
|
+
export const equals: {
|
|
6
|
+
(a: unknown, b: unknown): boolean
|
|
7
|
+
(a: unknown): (c: unknown) => boolean
|
|
8
|
+
}
|
|
9
|
+
export const eq: {
|
|
10
|
+
(a: unknown, b: unknown): boolean
|
|
11
|
+
(a: unknown): (c: unknown) => boolean
|
|
12
|
+
}
|
|
13
|
+
export const different: {
|
|
14
|
+
(a: unknown, b: unknown): boolean
|
|
15
|
+
(a: unknown): (c: unknown) => boolean
|
|
16
|
+
}
|
|
17
|
+
export const diff: {
|
|
18
|
+
(a: unknown, b: unknown): boolean
|
|
19
|
+
(a: unknown): (c: unknown) => boolean
|
|
20
|
+
}
|
|
21
|
+
export const flatten: <T>(...arr: (T | T[])[]) => T[]
|
|
22
|
+
export const loop: <T, R>(fn: ((item: T) => R) | T, ...items: any[]) => any
|
|
23
|
+
export const merge: <T, U>(o1: T, o2: U) => any
|
|
24
|
+
declare namespace _default {
|
|
25
|
+
export { equal }
|
|
26
|
+
export { equals }
|
|
27
|
+
export { eq }
|
|
28
|
+
export { different }
|
|
29
|
+
export { diff }
|
|
30
|
+
export { flatten }
|
|
31
|
+
export { loop }
|
|
32
|
+
export { merge }
|
|
33
|
+
}
|
|
34
|
+
export default _default
|
package/types/loop.d.ts
ADDED
package/types/merge.d.ts
ADDED
package/src/flatten.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import is from '@magic/types'
|
|
2
|
-
|
|
3
|
-
export const shallow = flat => (is.array(flat) ? flatten(...flat) : flat)
|
|
4
|
-
|
|
5
|
-
export const concat = (flat, deep) => flat.concat(shallow(deep))
|
|
6
|
-
|
|
7
|
-
export const flatten = (...arr) => arr.reduce(concat, [])
|
|
8
|
-
|
|
9
|
-
export default flatten
|
package/src/loop.mjs
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import is from '@magic/types'
|
|
2
|
-
|
|
3
|
-
export const loop = (fn, ...items) => {
|
|
4
|
-
if (is.empty(items)) {
|
|
5
|
-
if (is.fn(fn)) {
|
|
6
|
-
return fn(...items)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
return
|
|
10
|
-
} else if (items.length === 1) {
|
|
11
|
-
items = items[0]
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (!is.function(fn) && is.function(items)) {
|
|
15
|
-
const oldFn = fn
|
|
16
|
-
fn = items
|
|
17
|
-
items = oldFn
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (!is.function(fn)) {
|
|
21
|
-
return [fn, items]
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (!items) {
|
|
25
|
-
return fn(items)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!is.function(items.map)) {
|
|
29
|
-
return fn(items)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return items.map(item => loop(fn, item))
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export default loop
|