-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
Copy pathmerge.js
58 lines (48 loc) · 1.98 KB
/
merge.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* @prettier
*
* We're currently stuck with using deep-extend as it handles the following case:
*
* deepExtend({ a: 1 }, { a: undefined }) => { a: undefined }
*
* NOTE1: lodash.merge & lodash.mergeWith prefers to ignore undefined values
* NOTE2: special handling of `domNode` option is now required as `deep-extend` will corrupt it (lodash.merge handles it correctly)
* NOTE3: oauth2RedirectUrl option can be set to undefined. By expecting null instead of undefined, we can't use lodash.merge.
* NOTE4: urls.primaryName needs to handled in special way, because it's an arbitrary property on Array instance
*
* TODO([email protected]): remove deep-extend in favor of lodash.merge
*/
import deepExtend from "deep-extend"
import typeCast from "./type-cast"
const merge = (target, ...sources) => {
let domNode = Symbol.for("domNode")
let primaryName = Symbol.for("primaryName")
const sourcesWithoutExceptions = []
for (const source of sources) {
const sourceWithoutExceptions = { ...source }
if (Object.hasOwn(sourceWithoutExceptions, "domNode")) {
domNode = sourceWithoutExceptions.domNode
delete sourceWithoutExceptions.domNode
}
if (Object.hasOwn(sourceWithoutExceptions, "urls.primaryName")) {
primaryName = sourceWithoutExceptions["urls.primaryName"]
delete sourceWithoutExceptions["urls.primaryName"]
} else if (
Array.isArray(sourceWithoutExceptions.urls) &&
Object.hasOwn(sourceWithoutExceptions.urls, "primaryName")
) {
primaryName = sourceWithoutExceptions.urls.primaryName
delete sourceWithoutExceptions.urls.primaryName
}
sourcesWithoutExceptions.push(sourceWithoutExceptions)
}
const merged = deepExtend(target, ...sourcesWithoutExceptions)
if (domNode !== Symbol.for("domNode")) {
merged.domNode = domNode
}
if (primaryName !== Symbol.for("primaryName") && Array.isArray(merged.urls)) {
merged.urls.primaryName = primaryName
}
return typeCast(merged)
}
export default merge