Text Diff
Compute differences between texts or files
Source Code
import fs from "fs";
import path from "path";
import { diffLines, diffWords, createPatch } from "diff";
const [inputPathA, inputPathB, outputPath, format = "unified"] = process.argv.slice(2);
if (!inputPathA || !inputPathB || !outputPath) {
console.error("Usage: inputPathA inputPathB outputPath [format]");
process.exit(1);
}
try {
console.log(`Computing diff...`);
console.log(` File A: ${inputPathA}`);
console.log(` File B: ${inputPathB}`);
const textA = fs.readFileSync(inputPathA, "utf-8");
const textB = fs.readFileSync(inputPathB, "utf-8");
let output;
let stats = { additions: 0, deletions: 0, changes: 0 };
if (format === "unified") {
// Generate unified diff patch
output = createPatch(path.basename(inputPathA), textA, textB, "original", "modified");
// Count changes from the patch
const lines = output.split("\n");
for (const line of lines) {
if (line.startsWith("+") && !line.startsWith("+++")) stats.additions++;
if (line.startsWith("-") && !line.startsWith("---")) stats.deletions++;
}
} else if (format === "json") {
// Generate structured JSON diff
const changes = diffLines(textA, textB);
output = JSON.stringify(
changes.map((part) => ({
type: part.added ? "added" : part.removed ? "removed" : "unchanged",
value: part.value,
lines: part.count || 0,
})),
null,
2
);
for (const part of changes) {
if (part.added) stats.additions += part.count || 1;
if (part.removed) stats.deletions += part.count || 1;
}
} else if (format === "words") {
// Word-level diff
const changes = diffWords(textA, textB);
output = JSON.stringify(
changes.map((part) => ({
type: part.added ? "added" : part.removed ? "removed" : "unchanged",
value: part.value,
})),
null,
2
);
for (const part of changes) {
if (part.added) stats.additions++;
if (part.removed) stats.deletions++;
}
} else {
console.error(`Unknown format: ${format}. Use: unified, json, words`);
process.exit(1);
}
stats.changes = stats.additions + stats.deletions;
// Ensure output directory exists
const dir = path.dirname(outputPath);
if (dir && dir !== ".") {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(outputPath, output);
const identical = stats.changes === 0;
console.log(`\nā Computed diff`);
console.log(` Format: ${format}`);
console.log(` Additions: ${stats.additions}`);
console.log(` Deletions: ${stats.deletions}`);
console.log(` Identical: ${identical}`);
console.log(` Written to: ${outputPath}`);
console.log(
JSON.stringify({
success: true,
inputPathA,
inputPathB,
outputPath,
format,
identical,
...stats,
})
);
} catch (error) {
console.error("Error:", error.message);
process.exit(1);
}