json-diff-kit
Advanced tools
Comparing version 1.0.1 to 1.0.4
@@ -46,5 +46,5 @@ // src/utils/detect-circular.ts | ||
if (typeof value === "string") { | ||
return `"${value}"`; | ||
return stringify_default(value); | ||
} | ||
return String(value); | ||
return stringify_default(value); | ||
}; | ||
@@ -78,8 +78,22 @@ var format_value_default = formatValue; | ||
} else if (lhs === null || lhs === void 0) { | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ level, type: "add", text: format_value_default(rhs) }); | ||
const addedLines = stringify_default(rhs, null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "add", | ||
text: addedLines[i].replace(/^\s+/, "").replace(/,$/g, "") | ||
}); | ||
} | ||
return [linesLeft, linesRight]; | ||
} else if (rhs === null || rhs === void 0) { | ||
linesLeft.push({ level, type: "remove", text: format_value_default(lhs) }); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
const addedLines = stringify_default(lhs, null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
linesLeft.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "remove", | ||
text: addedLines[i].replace(/^\s+/, "").replace(/,$/g, "") | ||
}); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
} | ||
return [linesLeft, linesRight]; | ||
@@ -137,14 +151,46 @@ } | ||
if (keyLeft < keyRight) { | ||
linesLeft.push({ level, type: "remove", text: `"${keyLeft}": ${format_value_default(lhs[keyLeft])}` }); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
const addedLines = stringify_default(lhs[keyLeft], null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
const text = addedLines[i].replace(/^\s+/, "").replace(/,$/g, ""); | ||
linesLeft.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "remove", | ||
text: i ? text : `"${keyLeft}": ${text}` | ||
}); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
} | ||
} else { | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ level, type: "add", text: `"${keyRight}": ${format_value_default(rhs[keyRight])}` }); | ||
const addedLines = stringify_default(rhs[keyRight], null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
const text = addedLines[i].replace(/^\s+/, "").replace(/,$/g, ""); | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "add", | ||
text: i ? text : `"${keyRight}": ${text}` | ||
}); | ||
} | ||
} | ||
} else if (keyLeft) { | ||
linesLeft.push({ level, type: "remove", text: `"${keyLeft}": ${format_value_default(lhs[keyLeft])}` }); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
const addedLines = stringify_default(lhs[keyLeft], null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
const text = addedLines[i].replace(/^\s+/, "").replace(/,$/g, ""); | ||
linesLeft.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "remove", | ||
text: i ? text : `"${keyLeft}": ${text}` | ||
}); | ||
linesRight.push({ level, type: "equal", text: "" }); | ||
} | ||
} else if (keyRight) { | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ level, type: "add", text: `"${keyRight}": ${format_value_default(rhs[keyRight])}` }); | ||
const addedLines = stringify_default(rhs[keyRight], null, 1).split("\n"); | ||
for (let i = 0; i < addedLines.length; i++) { | ||
const text = addedLines[i].replace(/^\s+/, "").replace(/,$/g, ""); | ||
linesLeft.push({ level, type: "equal", text: "" }); | ||
linesRight.push({ | ||
level: level + (addedLines[i].match(/^\s+/)?.[0]?.length || 0), | ||
type: "add", | ||
text: i ? text : `"${keyRight}": ${text}` | ||
}); | ||
} | ||
} | ||
@@ -232,9 +278,23 @@ if (!keyLeft) { | ||
} else { | ||
tLeft.unshift({ level: level + 1, type: "remove", text: format_value_default(arrLeft[i - 1]) }); | ||
tRight.unshift({ level: level + 1, type: "equal", text: "" }); | ||
const addedLines = stringify_default(arrLeft[i - 1], null, 1).split("\n"); | ||
for (let i2 = addedLines.length - 1; i2 >= 0; i2--) { | ||
tLeft.unshift({ | ||
level: level + 1 + (addedLines[i2].match(/^\s+/)?.[0]?.length || 0), | ||
type: "remove", | ||
text: addedLines[i2].replace(/^\s+/, "").replace(/,$/g, "") | ||
}); | ||
tRight.unshift({ level: level + 1, type: "equal", text: "" }); | ||
} | ||
i--; | ||
} | ||
} else { | ||
tLeft.unshift({ level: level + 1, type: "equal", text: "" }); | ||
tRight.unshift({ level: level + 1, type: "add", text: format_value_default(arrRight[j - 1]) }); | ||
const addedLines = stringify_default(arrRight[j - 1], null, 1).split("\n"); | ||
for (let i2 = addedLines.length - 1; i2 >= 0; i2--) { | ||
tLeft.unshift({ level: level + 1, type: "equal", text: "" }); | ||
tRight.unshift({ | ||
level: level + 1 + (addedLines[i2].match(/^\s+/)?.[0]?.length || 0), | ||
type: "add", | ||
text: addedLines[i2].replace(/^\s+/, "").replace(/,$/g, "") | ||
}); | ||
} | ||
j--; | ||
@@ -526,2 +586,63 @@ } | ||
import * as React from "react"; | ||
// src/utils/get-inline-diff.ts | ||
var lcsString = (l, r) => { | ||
const f = Array(l.length + 1).fill(0).map(() => Array(r.length + 1).fill(0)); | ||
const backtrack = Array(l.length + 1).fill(0).map(() => Array(r.length + 1).fill(0)); | ||
for (let i2 = 1; i2 <= l.length; i2++) | ||
backtrack[i2][0] = "up"; | ||
for (let j2 = 1; j2 <= r.length; j2++) | ||
backtrack[0][j2] = "left"; | ||
for (let i2 = 1; i2 <= l.length; i2++) { | ||
for (let j2 = 1; j2 <= r.length; j2++) { | ||
if (l[i2 - 1] === r[j2 - 1]) { | ||
f[i2][j2] = f[i2 - 1][j2 - 1] + 1; | ||
backtrack[i2][j2] = "diag"; | ||
} else if (f[i2 - 1][j2] >= f[i2][j2 - 1]) { | ||
f[i2][j2] = f[i2 - 1][j2]; | ||
backtrack[i2][j2] = "up"; | ||
} else { | ||
f[i2][j2] = f[i2][j2 - 1]; | ||
backtrack[i2][j2] = "left"; | ||
} | ||
} | ||
} | ||
let i = l.length; | ||
let j = r.length; | ||
const tLeft = []; | ||
const tRight = []; | ||
while (i > 0 || j > 0) { | ||
if (backtrack[i][j] === "diag") { | ||
if (!tLeft.length || tLeft[0].type !== "equal") { | ||
tLeft.unshift({ type: "equal", text: "" }); | ||
} | ||
if (!tRight.length || tRight[0].type !== "equal") { | ||
tRight.unshift({ type: "equal", text: "" }); | ||
} | ||
tLeft[0].text = l[i - 1] + tLeft[0].text; | ||
tRight[0].text = r[j - 1] + tRight[0].text; | ||
i--; | ||
j--; | ||
} else if (backtrack[i][j] === "up") { | ||
if (!tLeft.length || tLeft[0].type !== "remove") { | ||
tLeft.unshift({ type: "remove", text: "" }); | ||
} | ||
tLeft[0].text = l[i - 1] + tLeft[0].text; | ||
i--; | ||
} else { | ||
if (!tRight.length || tRight[0].type !== "add") { | ||
tRight.unshift({ type: "add", text: "" }); | ||
} | ||
tRight[0].text = r[j - 1] + tRight[0].text; | ||
j--; | ||
} | ||
} | ||
return [tLeft, tRight]; | ||
}; | ||
var getInlineDiff = (l, r) => { | ||
return lcsString(l, r); | ||
}; | ||
var get_inline_diff_default = getInlineDiff; | ||
// src/viewer.tsx | ||
var Viewer = (props) => { | ||
@@ -533,5 +654,19 @@ const [linesLeft, linesRight] = props.diff; | ||
const indentSize = indent === "tab" ? 1 : indent; | ||
const renderInlineDiffResult = (arr) => { | ||
return arr.map((result) => /* @__PURE__ */ React.createElement(React.Fragment, null, result.map((item, index) => { | ||
if (item.type === "equal") { | ||
return /* @__PURE__ */ React.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}` | ||
}, item.text); | ||
} | ||
return /* @__PURE__ */ React.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}`, | ||
className: `inline-diff-${item.type}` | ||
}, item.text); | ||
}))); | ||
}; | ||
const renderLine = (index) => { | ||
const l = linesLeft[index]; | ||
const r = linesRight[index]; | ||
const [lText, rText] = props.highlightInlineDiff && l.type === "modify" && r.type === "modify" ? renderInlineDiffResult(get_inline_diff_default(l.text, r.text)) : [l.text, r.text]; | ||
return /* @__PURE__ */ React.createElement("tr", { | ||
@@ -544,3 +679,3 @@ key: index | ||
className: `line-${l.type}` | ||
}, /* @__PURE__ */ React.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), l.text, l.comma && ",")), props.lineNumbers && /* @__PURE__ */ React.createElement("td", { | ||
}, /* @__PURE__ */ React.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), lText, l.comma && ",")), props.lineNumbers && /* @__PURE__ */ React.createElement("td", { | ||
className: `line-${r.type} line-number`, | ||
@@ -550,3 +685,3 @@ style: { width: lineNumberWidth } | ||
className: `line-${r.type}` | ||
}, /* @__PURE__ */ React.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), r.text, r.comma && ","))); | ||
}, /* @__PURE__ */ React.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), rText, r.comma && ","))); | ||
}; | ||
@@ -553,0 +688,0 @@ return /* @__PURE__ */ React.createElement("table", { |
{ | ||
"name": "json-diff-kit", | ||
"version": "1.0.1", | ||
"version": "1.0.4", | ||
"description": "A better JSON differ & viewer.", | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"typings": "typings", | ||
"scripts": { | ||
"start": "rollup -c -w", | ||
"dev": "pnpm start", | ||
"test": "jest --coverage", | ||
"build": "node ./esbuild.mjs && tsc", | ||
"build:pages": "NODE_ENV=production BASEDIR=docs rollup -c", | ||
"prepublish": "pnpm build" | ||
}, | ||
"repository": { | ||
@@ -45,11 +53,3 @@ "type": "git", | ||
"react-dom": "^17.0.0 || ^16.0.0" | ||
}, | ||
"scripts": { | ||
"start": "rollup -c -w", | ||
"dev": "pnpm start", | ||
"test": "jest --coverage", | ||
"build": "node ./esbuild.mjs && tsc", | ||
"build:pages": "NODE_ENV=production BASEDIR=docs rollup -c" | ||
}, | ||
"readme": "# JSON Diff Kit\n\n[![NPM version][npm-image]][npm-url]\n[![Downloads][download-badge]][npm-url]\n[![Codecov](https://codecov.io/gh/RexSkz/json-diff-kit/branch/master/graph/badge.svg?token=8YRG3M4WTO)](https://codecov.io/gh/RexSkz/json-diff-kit)\n\nA better JSON differ & viewer.\n\n> Notice: considering most of the browsers now support ES6, this library has only the ES6 version. If you need the compatibility with older browsers, please configure the compiler in your project (e.g. add this library to the `include` field in `babel.config.js`).\n\n## Install\n\nYou can install `json-diff-kit` via various package managers.\n\n```sh\n# using npm\nnpm i json-diff-kit --save\n\n# using yarn\nyarn add json-diff-kit\n\n# using pnpm\npnpm add json-diff-kit\n```\n\n## Quick Start\n\nTo generate the diff data:\n\n```ts\nimport { Differ } from 'json-diff-kit';\n\nconst before = {\n a: 1,\n b: 2,\n d: [1, 5, 4],\n e: ['1', 2, { f: 3, g: null, h: [5], i: [] }, 9],\n};\nconst after = {\n b: 2,\n c: 3,\n d: [1, 3, 4, 6],\n e: ['1', 2, 3, { f: 4, g: false, i: [7, 8] }, 10],\n};\n\n// all configs are optional\nconst differ = new Differ({\n detectCircular: true, // default `true`\n maxDepth: Infinity, // default `Infinity`\n showModifications: true, // default `true`\n arrayDiffMethod: 'lcs', // default `\"normal\"`\n});\n\nconst diff = differ.diff(before, after);\nconsole.log(diff);\n```\n\nYou can use your own component to visualize the `diff` data, or use the built-in viewer:\n\n```tsx\nimport { Viewer } from 'json-diff-kit';\nimport type { DiffResult } from 'json-diff-kit';\n\nimport 'json-diff-kit/dist/viewer.css';\n\ninterface PageProps {\n diff: [DiffResult[], DiffResult[]];\n}\n\nconst Page: React.FC<PageProps> = props => {\n return (\n <Viewer\n diff={props.diff} // required\n indent={4} // default `2`\n lineNumbers={true} // default `false`\n />\n );\n};\n```\n\nThe result is here:\n\n![The result (using LCS array diff method).](./preview.png)\n\n## More Complex Usages\n\nPlease check the [demo pages](https://json-diff-kit.js.org/).\n\n## Algorithm Details\n\nPlease refer to the article [JSON Diff Kit: A Combination of Several Simple Algorithms](https://blog.rexskz.info/json-diff-kit-a-combination-of-several-simple-algorithms.html).\n\n## License\n\nMIT\n\n[npm-url]: https://npmjs.org/package/json-diff-kit\n[npm-image]: https://img.shields.io/npm/v/json-diff-kit.svg\n\n[download-badge]: https://img.shields.io/npm/dm/json-diff-kit.svg\n" | ||
} | ||
} | ||
} |
@@ -0,0 +0,0 @@ export interface DifferOptions { |
@@ -0,0 +0,0 @@ import Differ from './differ'; |
declare const detectCircular: (value: any, map?: Map<any, boolean>) => boolean; | ||
export default detectCircular; |
import type { DifferOptions, DiffResult } from '../differ'; | ||
declare const diffArrayLCS: (arrLeft: any[], arrRight: any[], keyLeft: string, keyRight: string, level: number, options: DifferOptions, linesLeft?: DiffResult[], linesRight?: DiffResult[]) => [DiffResult[], DiffResult[]]; | ||
export default diffArrayLCS; |
import type { DiffResult, DifferOptions } from '../differ'; | ||
declare const diffArrayNormal: (arrLeft: any[], arrRight: any[], keyLeft: string, keyRight: string, level: number, options: DifferOptions, linesLeft?: DiffResult[], linesRight?: DiffResult[]) => [DiffResult[], DiffResult[]]; | ||
export default diffArrayNormal; |
import type { DifferOptions, DiffResult, ArrayDiffFunc } from '../differ'; | ||
declare const diffObject: (lhs: Record<string, any>, rhs: Record<string, any>, level: number, options: DifferOptions, arrayDiffFunc: ArrayDiffFunc) => [DiffResult[], DiffResult[]]; | ||
export default diffObject; |
declare const formatValue: (value: any, depth?: number) => string; | ||
export default formatValue; |
export {}; |
declare const getType: (value: any) => "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null" | "array"; | ||
export default getType; |
export {}; |
@@ -0,0 +0,0 @@ /** |
export {}; |
declare const stringify: (obj: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number, depth?: number) => string; | ||
export default stringify; |
export {}; |
@@ -16,2 +16,4 @@ import * as React from 'react'; | ||
lineNumbers?: boolean; | ||
/** Whether to show the inline diff highlight, default is `true`. */ | ||
highlightInlineDiff?: boolean; | ||
/** Extra class names */ | ||
@@ -18,0 +20,0 @@ className?: string; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
127620
40
1515
0