diff-mcp

diff-mcp

比较两个文本或数据(支持文本差异、JSON、JSON5、YAML、TOML、XML 和 HTML)。由 jsondiffpatch 提供支持。 (Bǐjiào liǎng gè wénběn huò shùjù (zhīchí wénběn chāyì, JSON, JSON5, YAML, TOML, XML hé HTML). Yóu jsondiffpatch tígōng zhīchí.)

Category
访问服务器

README

<p align="center"> <img src="demos/html-demo/logo.svg" width="48px" align="center" alt="jsondiffpatch logo" /> <h1 align="center">jsondiffpatch</h1> <p align="center"> <a href="https://jsondiffpatch.com">jsondiffpatch.com</a> <br/> Diff & patch JavaScript 对象 </p> </p>

<!--- badges --> <p align="center"> <a href="https://github.com/benjamine/jsondiffpatch/actions?query=branch%3Amaster"><img src="https://github.com/benjamine/jsondiffpatch/actions/workflows/CI.yml/badge.svg?event=push&branch=master" alt="JsonDiffPatch CI status" /></a> <a href="https://twitter.com/beneidel" rel="nofollow"><img src="https://img.shields.io/badge/created%20by-@beneidel-BACABA.svg" alt="Created by Benjamin Eidelman"></a> <a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://img.shields.io/github/license/benjamine/jsondiffpatch" alt="License"></a> <a href="https://www.npmjs.com/package/jsondiffpatch" rel="nofollow"><img src="https://img.shields.io/npm/dw/jsondiffpatch.svg" alt="npm"></a> <a href="https://github.com/benjamine/jsondiffpatch" rel="nofollow"><img src="https://img.shields.io/github/stars/benjamine/jsondiffpatch" alt="stars"></a> </p>


在线演示

  • min+gzipped ~ 16KB
  • 浏览器和服务器 (仅 ESM)
  • 深度 diff,使用 delta 进行 patch
  • 使用 LCS 的智能数组 diff,重要提示: 要匹配数组中的对象,您必须提供一个 objectHash 函数(这是对象匹配的方式,否则将使用按位置的简单匹配)。有关更多详细信息,请查看 数组 diff 文档
  • (可选)由 google-diff-match-patch 驱动的长字符串的文本 diff(字符级别 diff)
  • 反转 delta,取消 patch(例如,使用 delta 将对象恢复到其原始状态)
  • 多种输出格式:
    • 纯 JSON,低占用空间 delta 格式
    • <span style="background-color: #bbffbb; color: black;">可视化</span> <span style="background-color: #ffbbbb; color:black; text-decoration: line-through">diff</span> (html),请参阅 演示
    • 注释 JSON (html),以帮助解释带有注释的 delta 格式
    • JSON Patch (RFC 6902),可以生成 patch,也可以应用它们
    • 控制台(彩色),尝试运行 ./node_modules/.bin/jsondiffpatch left.json right.json
    • 编写你自己的!查看 格式化程序文档
  • 奖励:jsondiffpatch.clone(obj)(深度克隆)

支持的平台

用法

在你的终端上:

npx jsondiffpatch --help

console_demo!

或者作为库:

// 示例数据
const country = {
  name: 'Argentina',
  capital: 'Buenos Aires',
  independence: new Date(1816, 6, 9),
};

// 克隆 country,使用 dateReviver 处理 Date 对象
const country2 = JSON.parse(JSON.stringify(country), jsondiffpatch.dateReviver);

// 进行一些更改
country2.name = 'Republica Argentina';
country2.population = 41324992;
delete country2.capital;

const delta = jsondiffpatch.diff(country, country2);

assertSame(delta, {
  name: ['Argentina', 'Republica Argentina'], // 旧值,新值
  population: ['41324992'], // 新值
  capital: ['Buenos Aires', 0, 0], // 已删除
});

// patch 原始对象
jsondiffpatch.patch(country, delta);

// 反转 diff
const reverseDelta = jsondiffpatch.reverse(delta);
// 也可以使用以下方法将 country2 恢复到原始值:jsondiffpatch.unpatch(country2, delta);

const delta2 = jsondiffpatch.diff(country, country2);
assert(delta2 === undefined);
// undefined => 没有差异

数组 diff:

// 示例数据
const country = {
  name: 'Argentina',
  cities: [
    {
      name: 'Buenos Aires',
      population: 13028000,
    },
    {
      name: 'Cordoba',
      population: 1430023,
    },
    {
      name: 'Rosario',
      population: 1136286,
    },
    {
      name: 'Mendoza',
      population: 901126,
    },
    {
      name: 'San Miguel de Tucuman',
      population: 800000,
    },
  ],
};

// 克隆 country
const country2 = JSON.parse(JSON.stringify(country));

// 删除 Cordoba
country.cities.splice(1, 1);

// 添加 La Plata
country.cities.splice(4, 0, {
  name: 'La Plata',
});

// 修改 Rosario,并移动它
const rosario = country.cities.splice(1, 1)[0];
rosario.population += 1234;
country.cities.push(rosario);

// 创建一个配置的实例,按名称匹配对象
const diffpatcher = jsondiffpatch.create({
  objectHash: function (obj) {
    return obj.name;
  },
});

const delta = diffpatcher.diff(country, country2);

assertSame(delta, {
  cities: {
    _t: 'a', // 表示此节点是一个数组(而不是一个对象)
    1: [
      // 在索引 1 处插入
      {
        name: 'Cordoba',
        population: 1430023,
      },
    ],
    2: {
      // 在索引 2 处修改 population (Rosario)
      population: [1137520, 1136286],
    },
    _3: [
      // 从索引 3 处删除
      {
        name: 'La Plata',
      },
      0,
      0,
    ],
    _4: [
      // 从索引 4 移动到索引 2
      '',
      2,
      3,
    ],
  },
});

有关更多示例(嵌套对象或数组,长文本 diff),请查看 packages/jsondiffpatch/test/examples/

如果你想了解 deltas,请参阅 delta 格式文档

安装

NPM

这适用于 node,或者如果你已经在你的应用程序上进行捆绑,则适用于浏览器

npm install jsondiffpatch
import {* as jsondiffpatch} from 'jsondiffpatch';
const jsondiffpatchInstance = jsondiffpatch.create(options);

浏览器

在浏览器中,你可以使用像 esm.shSkypack 这样的工具加载一个 bundle。

选项

import * as jsondiffpatch from 'jsondiffpatch';

// 仅当你想使用 diff-match-patch 进行文本 diff 时才导入
import { diff_match_patch } from '@dmsnell/diff-match-patch';

const jsondiffpatchInstance = jsondiffpatch.create({
  // 用于在 diff 数组时匹配对象,默认情况下仅使用 === 运算符
  objectHash: function (obj) {
    // 仅当对象通过引用不相等时才使用此函数
    return obj._id || obj.id;
  },
  arrays: {
    // 默认为 true,检测数组内部移动的项目(否则它们将被注册为删除+添加)
    detectMove: true,
    // 默认为 false,移动的项的值不包含在 deltas 中
    includeValueOnMove: false,
  },
  textDiff: {
    // 如果使用文本 diff,则需要通过此属性传入 diff-match-patch 库。
    // 或者,你可以使用 `jsondiffpatch/with-text-diffs` 导入 jsondiffpatch,以避免必须通过选项传入 diff-match-patch。
    diffMatchPatch: diff_match_patch,
    // 默认 60,使用文本 diff 算法的最小字符串长度(左侧和右侧):google-diff-match-patch
    minLength: 60,
  },
  propertyFilter: function (name, context) {
    /*
       可以指定此可选函数来忽略对象属性(例如,易失性数据)
        name:属性名称,存在于 context.left 或 context.right 对象中
        context:diff 上下文(具有 context.left 和 context.right 对象)
      */
    return name.slice(0, 1) !== '$';
  },
  cloneDiffValues: false /* 默认 false。如果为 true,则将克隆获得的 delta 中的值
      (默认情况下使用 jsondiffpatch.clone),以确保 delta 不保留对左侧或右侧对象的引用。 如果你多次 diff 和 patch 同一个对象而不序列化 deltas,这将变得很有用。
      可以指定一个函数来提供自定义 clone(value) 而不是 true。
      */
  omitRemovedValues: false /* 如果你不需要 unpatch(反转 deltas),
      "old"/"left" 值(已删除或替换)不包含在 delta 中。
      你可以将此设置为 true 以获得更紧凑的 deltas。
      */,
});

可视化 Diff

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css" type="text/css" />
    <link
      rel="stylesheet"
      href="https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/html.css"
      type="text/css"
    />
    <link
      rel="stylesheet"
      href="https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/annotated.css"
      type="text/css"
    />
  </head>
  <body>
    <div id="visual"></div>
    <hr />
    <div id="annotated"></div>
    <script type="module">
      import * as jsondiffpatch from 'https://esm.sh/jsondiffpatch@0.6.0';
      import * as annotatedFormatter from 'https://esm.sh/jsondiffpatch@0.6.0/formatters/annotated';
      import * as htmlFormatter from 'https://esm.sh/jsondiffpatch@0.6.0/formatters/html';

      const left = { a: 3, b: 4 };
      const right = { a: 5, c: 9 };
      const delta = jsondiffpatch.diff(left, right);

      // 美观的 html diff
      document.getElementById('visual').innerHTML = htmlFormatter.format(
        delta,
        left,
      );

      // 自解释 json
      document.getElementById('annotated').innerHTML =
        annotatedFormatter.format(delta, left);
    </script>
  </body>
</html>

要查看格式化程序的实际效果,请查看 在线演示

有关更多详细信息,请查看 格式化程序文档

插件

diff(), patch()reverse() 函数是使用 Pipes & Filters 模式实现的,通过在管道上添加或替换过滤器,使其具有极高的可定制性。

有关详细信息,请查看 插件文档

相关项目

所有贡献者 ✨

<a href="https://github.com/benjamine/jsondiffpatch/graphs/contributors"> <p align="center"> <img width="720" src="https://contrib.rocks/image?repo=benjamine/jsondiffpatch" alt="A table of avatars from the project's contributors" /> </p> </a>

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选