forked from falsecz/3-way-merge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.coffee
50 lines (39 loc) · 1.25 KB
/
index.coffee
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
###
Function for 3-way merge
@param {Object} o (original)
@param {Object} a (current)
@param {Object} b (new)
@return {Object} Merged result
###
merge = (o, a, b) ->
throw new Error 'Merge original document must be an object!' if typeof o isnt 'object'
throw new Error 'Merge current document must be an object!' if typeof a isnt 'object'
throw new Error 'Merge new document must be an object!' if typeof b isnt 'object'
isArray = Array.isArray b
result = if isArray then [] else {}
if isArray
a = [] if not Array.isArray a
o = [] if not Array.isArray o
for k of a
unless a[k] not in b and a[k] in o
result.push a[k]
for k of b
if typeof a[k] is 'object' and typeof b[k] is 'object'
ov = if k of o and typeof o[k] is 'object' then o[k] else {}
result[k] = merge ov, a[k], b[k]
else if b[k] not in a and b[k] not in o
result.push b[k]
else
a = {} if Array.isArray a
for k of b
unless o[k] is b[k] and o[k] isnt a[k]
result[k] = b[k]
for k of a
if a[k] isnt result[k]
if typeof a[k] is 'object' and typeof b?[k] is 'object'
ov = if o? and k of o and typeof o[k] is 'object' then o[k] else {}
result[k] = merge ov, a[k], b[k]
else if b?[k] is o?[k]
result[k] = a[k]
result
module.exports = merge