jsondiffpatch-html 1.0.0
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 +28 -0
- package/bin/jsondiffpatch-html.js +196 -0
- package/left.json +7 -0
- package/package.json +29 -0
- package/right.json +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# jsondiffpatch-html
|
|
2
|
+
|
|
3
|
+
CLI tool to generate HTML diff reports from JSON files using `jsondiffpatch`.
|
|
4
|
+
|
|
5
|
+
## Install Dependecies
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Add execute permission
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
chmod +x bin/jsondiffpatch-html.js
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Link the command
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
npm link
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Run the command
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
jsondiffpatch-html left.json right.json -o diff.html
|
|
27
|
+
```
|
|
28
|
+
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { create } from 'jsondiffpatch';
|
|
4
|
+
import * as htmlFormatter from 'jsondiffpatch/formatters/html';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 统计 jsondiffpatch delta 中「第一级属性」的差异
|
|
8
|
+
*
|
|
9
|
+
* @param {object} delta jsondiffpatch.diff(left, right) 的结果
|
|
10
|
+
* @returns {{
|
|
11
|
+
* added: string[],
|
|
12
|
+
* removed: string[],
|
|
13
|
+
* updated: string[]
|
|
14
|
+
* }}
|
|
15
|
+
*/
|
|
16
|
+
function statTopLevelDiff(delta) {
|
|
17
|
+
const result = {
|
|
18
|
+
added: [],
|
|
19
|
+
removed: [],
|
|
20
|
+
updated: [],
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
if (!delta || typeof delta !== 'object') {
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (const key of Object.keys(delta)) {
|
|
28
|
+
if (key === '_t') continue; // 忽略数组标记
|
|
29
|
+
|
|
30
|
+
const value = delta[key];
|
|
31
|
+
|
|
32
|
+
// 情况 1:数组形式(新增 / 删除 / 替换)
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
// 新增:[newValue]
|
|
35
|
+
if (value.length === 1) {
|
|
36
|
+
result.added.push(key);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 删除:[oldValue, 0, 0]
|
|
41
|
+
if (value.length === 3 && value[1] === 0 && value[2] === 0) {
|
|
42
|
+
result.removed.push(key);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 替换:[oldValue, newValue]
|
|
47
|
+
if (value.length === 2) {
|
|
48
|
+
result.updated.push(key);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 情况 2:对象形式 → 子属性发生变化
|
|
54
|
+
if (typeof value === 'object') {
|
|
55
|
+
result.updated.push(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 创建实例
|
|
63
|
+
const jdp = create();
|
|
64
|
+
|
|
65
|
+
// CLI 参数解析
|
|
66
|
+
const args = process.argv.slice(2);
|
|
67
|
+
if (args.length < 2) {
|
|
68
|
+
console.error(`Usage: jsondiffpatch-html old.json new.json [-o output.html]`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const oldFile = args[0];
|
|
73
|
+
const newFile = args[1];
|
|
74
|
+
|
|
75
|
+
let outFile = 'diff.html';
|
|
76
|
+
const oIdx = args.indexOf('-o');
|
|
77
|
+
if (oIdx >= 0 && args[oIdx + 1]) {
|
|
78
|
+
outFile = args[oIdx + 1];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 读取 JSON
|
|
82
|
+
const left = JSON.parse(fs.readFileSync(oldFile, 'utf8'));
|
|
83
|
+
const right = JSON.parse(fs.readFileSync(newFile, 'utf8'));
|
|
84
|
+
|
|
85
|
+
// 生成 delta
|
|
86
|
+
const delta = jdp.diff(left, right);
|
|
87
|
+
|
|
88
|
+
const diffContent = delta ? htmlFormatter.format(delta, left) : "No diff";
|
|
89
|
+
const statistics = statTopLevelDiff(delta);
|
|
90
|
+
|
|
91
|
+
// 生成 HTML
|
|
92
|
+
// 通过实例访问 jdp.formatters.html
|
|
93
|
+
const releasedPkgUrl = "https://esm.sh/jsondiffpatch@0.6.0";
|
|
94
|
+
const htmlContent = `
|
|
95
|
+
<!DOCTYPE html>
|
|
96
|
+
<html lang="en">
|
|
97
|
+
<head>
|
|
98
|
+
<meta charset="UTF-8">
|
|
99
|
+
<title>JSON Diff Report</title>
|
|
100
|
+
<link
|
|
101
|
+
rel="stylesheet"
|
|
102
|
+
href="${releasedPkgUrl}/lib/formatters/styles/html.css"
|
|
103
|
+
type="text/css"
|
|
104
|
+
/>
|
|
105
|
+
<link
|
|
106
|
+
rel="stylesheet"
|
|
107
|
+
href="${releasedPkgUrl}/lib/formatters/styles/annotated.css"
|
|
108
|
+
type="text/css"
|
|
109
|
+
/>
|
|
110
|
+
<script type="text/javascript">
|
|
111
|
+
|
|
112
|
+
const showUnchanged = (show, node, delay) => {
|
|
113
|
+
const el = node || document.body;
|
|
114
|
+
const prefix = 'jsondiffpatch-unchanged-';
|
|
115
|
+
const classes = {
|
|
116
|
+
showing: prefix + 'showing',
|
|
117
|
+
hiding: prefix + 'hiding',
|
|
118
|
+
visible: prefix + 'visible',
|
|
119
|
+
hidden: prefix + 'hidden',
|
|
120
|
+
};
|
|
121
|
+
const list = el.classList;
|
|
122
|
+
if (!list) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!delay) {
|
|
126
|
+
list.remove(classes.showing);
|
|
127
|
+
list.remove(classes.hiding);
|
|
128
|
+
list.remove(classes.visible);
|
|
129
|
+
list.remove(classes.hidden);
|
|
130
|
+
if (show === false) {
|
|
131
|
+
list.add(classes.hidden);
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (show === false) {
|
|
136
|
+
list.remove(classes.showing);
|
|
137
|
+
list.add(classes.visible);
|
|
138
|
+
setTimeout(() => {
|
|
139
|
+
list.add(classes.hiding);
|
|
140
|
+
}, 10);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
list.remove(classes.hiding);
|
|
144
|
+
list.add(classes.showing);
|
|
145
|
+
list.remove(classes.hidden);
|
|
146
|
+
}
|
|
147
|
+
const intervalId = setInterval(() => {
|
|
148
|
+
adjustArrows(el);
|
|
149
|
+
}, 100);
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
list.remove(classes.showing);
|
|
152
|
+
list.remove(classes.hiding);
|
|
153
|
+
if (show === false) {
|
|
154
|
+
list.add(classes.hidden);
|
|
155
|
+
list.remove(classes.visible);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
list.add(classes.visible);
|
|
159
|
+
list.remove(classes.hidden);
|
|
160
|
+
}
|
|
161
|
+
setTimeout(() => {
|
|
162
|
+
list.remove(classes.visible);
|
|
163
|
+
clearInterval(intervalId);
|
|
164
|
+
}, delay + 400);
|
|
165
|
+
}, delay);
|
|
166
|
+
};
|
|
167
|
+
const hideUnchanged = (node, delay) => showUnchanged(false, node, delay);
|
|
168
|
+
|
|
169
|
+
</script>
|
|
170
|
+
</head>
|
|
171
|
+
<body>
|
|
172
|
+
<input type="checkbox" id="hide-unchanged"><label>Hide unchanged<label>
|
|
173
|
+
<div>
|
|
174
|
+
<span>Added: ${statistics.added.length} ${statistics.added}</span><br/>
|
|
175
|
+
<span>Removed: ${statistics.removed.length} ${statistics.removed}</span><br/>
|
|
176
|
+
<span>Updated: ${statistics.updated.length} ${statistics.updated}</span>
|
|
177
|
+
</div>
|
|
178
|
+
<div id='the-diff'>
|
|
179
|
+
${diffContent}
|
|
180
|
+
</div>
|
|
181
|
+
<script type="text/javascript">
|
|
182
|
+
document.getElementById('hide-unchanged').addEventListener("change", (e) => {
|
|
183
|
+
const checked = e.target.checked;
|
|
184
|
+
if (checked) {
|
|
185
|
+
hideUnchanged();
|
|
186
|
+
} else {
|
|
187
|
+
showUnchanged(true);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
</script>
|
|
191
|
+
</body>
|
|
192
|
+
</html>
|
|
193
|
+
`;
|
|
194
|
+
|
|
195
|
+
fs.writeFileSync(outFile, htmlContent, 'utf8');
|
|
196
|
+
console.log(`HTML diff report generated: ${outFile}`);
|
package/left.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jsondiffpatch-html",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to generate HTML diff reports from JSON files using jsondiffpatch",
|
|
5
|
+
"main": "bin/jsondiffpatch-html.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jsondiffpatch-html": "bin/jsondiffpatch-html.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node bin/jsondiffpatch-html.js",
|
|
12
|
+
"build": "pkg . --targets node18-macos,node18-win,node18-linux --output dist/jsondiffpatch-html"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"json",
|
|
16
|
+
"diff",
|
|
17
|
+
"html",
|
|
18
|
+
"cli",
|
|
19
|
+
"jsondiffpatch"
|
|
20
|
+
],
|
|
21
|
+
"author": "Yaohui Wu",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"pkg": "^5.3.1"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"jsondiffpatch": "^0.6.1"
|
|
28
|
+
}
|
|
29
|
+
}
|