@dugongjs/cli
Version:
101 lines (100 loc) • 4.55 kB
JavaScript
import { Box, Spacer, Text } from "ink";
import { diff as jsonDiff } from "jsondiffpatch";
import React from "react";
import { Pane } from "../components/pane.js";
export const AggregateDiffPane = (props) => {
const { current, previous } = props;
const diff = React.useMemo(() => {
if (!current || !previous)
return null;
try {
return jsonDiff(previous, current);
}
catch (err) {
return { error: "Failed to compute diff" };
}
}, [current, previous]);
const renderDiff = (value, indent = 0) => {
if (value === undefined || value === null)
return [];
const lines = [];
const prefix = " ".repeat(indent * 2);
// Handle array diffs
if (value._t === "a") {
for (const key in value) {
if (key === "_t")
continue;
const index = key.startsWith("_") ? key.slice(1) : key;
const val = value[key];
if (Array.isArray(val) && val.length === 1) {
// Added
lines.push(React.createElement(Text, { key: `${key}-add` },
prefix,
"[+",
index,
"]: ",
React.createElement(Text, { color: "green" }, JSON.stringify(val[0]))));
}
else if (Array.isArray(val) && val.length === 3 && val[2] === 0) {
// Deleted
lines.push(React.createElement(Text, { key: `${key}-del` },
prefix,
"[-",
index,
"]: ",
React.createElement(Text, { color: "red" }, JSON.stringify(val[0]))));
}
else if (Array.isArray(val) && val.length === 2) {
// Changed
lines.push(React.createElement(Text, { key: `${key}-change` },
prefix,
"[~",
index,
"]: ",
React.createElement(Text, { color: "red" }, JSON.stringify(val[0])),
" \u2192",
" ",
React.createElement(Text, { color: "green" }, JSON.stringify(val[1]))));
}
}
return lines;
}
// Handle object diffs
for (const key in value) {
const val = value[key];
const isNested = typeof val === "object" && !Array.isArray(val) && val !== null;
if (Array.isArray(val) && val.length === 2 && typeof val[0] !== "object") {
lines.push(React.createElement(Text, { key: `${key}-${indent}` },
prefix,
React.createElement(Text, { color: "cyan" }, key),
": ",
React.createElement(Text, { color: "red" }, JSON.stringify(val[0])),
" \u2192",
" ",
React.createElement(Text, { color: "green" }, JSON.stringify(val[1]))));
}
else if (Array.isArray(val) && val.length === 3 && val[2] === 0) {
lines.push(React.createElement(Text, { key: `${key}-removed` },
prefix,
React.createElement(Text, { color: "cyan" }, key),
": ",
React.createElement(Text, { color: "red" },
JSON.stringify(val[0]),
" (deleted)")));
}
else if (isNested || (val && typeof val === "object" && val._t === "a")) {
lines.push(React.createElement(Text, { key: `${key}-head`, bold: true },
prefix,
React.createElement(Text, { color: "cyan" }, key),
":"));
lines.push(...renderDiff(val, indent + 1));
}
}
return lines;
};
return (React.createElement(Pane, null,
React.createElement(Text, { bold: true }, "Diff"),
!diff ? (React.createElement(Text, { color: "gray" }, "No changes detected.")) : (React.createElement(Box, { flexDirection: "column", marginTop: 1 }, renderDiff(diff))),
React.createElement(Spacer, null),
React.createElement(Text, { color: "gray", dimColor: true }, "Compares the current and previous state of the aggregate")));
};