-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff-object.js
More file actions
123 lines (114 loc) · 2.9 KB
/
Copy pathdiff-object.js
File metadata and controls
123 lines (114 loc) · 2.9 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
wrap Object.keys to avoid error on null or undefined
*/
function ok(obj) {
if (typeof obj !== 'object') return []
if (obj === null) return []
return Object.keys(obj)
}
/*
get distinct fields of objects
*/
function getFields(...args) {
const fields = args.reduce((arr, x) => (arr.push(...ok(x)), arr), [])
return [...new Set(fields)]
}
/*
show different fields of two objects
x,y: the objects you want to compare
name: whatever you want to name a object
*/
function showDifferentFields(x, y, name = 'obj') {
const obj = {}
diff(x, y, name)
return ok(obj).length ? obj : null
function diff(a, b, name = '') {
if (typeof a !== typeof b) {
obj[name] = [a, b]
return obj
}
if (typeof a !== 'object') {
if (a !== b) obj[name] = [a, b]
return obj
}
const keys = getFields(a, b)
keys.forEach(key => {
diff(a[key], b[key], [name, key].join('.'))
})
return obj
}
}
/*
get diff text
*/
function getText(x, y, depth = 1) {
const diff = (a, b) => a + (a === b ? '' : ` (${b}) <--`)
if (typeof x !== 'object') {
return diff(x, y) + '\n'
}
const keys = getFields(x, y)
let line = '\n'
keys.forEach(key => {
line += `${blank(depth)}${key}: ${getText(x[key], y[key], depth + 1)}`
})
return line
function blank(depth, count = 1) {
let prefix = '----', space = new Array(count + 1).join(prefix)
return new Array(depth + 1).join(space).replace(prefix, '').replace(/----$/, ' ').replace(/----/, ' ')
}
}
/*
get diff html
*/
function getHTML(x, y, depth = 1) {
const before = flag => `<div class="${flag ? 'b' : 'a'}">`, after = () => '</div>'
if (typeof x !== 'object') {
return diff(x, y)
}
const keys = getFields(x, y)
let line = `${before(1)}`
keys.forEach(key => {
line += `${before()}${key}: ${getHTML(x[key], y[key], depth + 1)}${after()}`
})
return line + `${after(1)}`
function diff(a, b) {
let hint = a === b ? '' : `<span class="c"> (${b}) </span>`
return a + hint
}
}
/*
save HTML to your folder
*/
function saveHTML(x, y, options = {}) {
const folder = options.folder || process.cwd()
const filename = options.filename || 'diff-object'
const path = require('path')
const fs = require('fs')
const exec = require('child_process').exec
const shell = cmd => new Promise((s, j) => exec(cmd, (e) => e ? j(e) : s())) // run shell command
const mkdirp = folder => shell(`mkdir -p ${folder}`) // create folder recursively
mkdirp(folder)
const file = path.join(folder, `${filename}.html`)
const style = fs.readFileSync(path.join(__dirname, 'diff-object.css'))
const body = getHTML(x, y)
const tpl = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${filename}</title>
<style>
${style}
</style>
</head>
<body>
${body}
</body>
</html>`
fs.writeFileSync(file, tpl)
}
module.exports = {
showDifferentFields,
getText,
getHTML,
saveHTML
}