UNPKG

diffling

Version:

A versatile diff computation package, supporting various diff methods and line-by-line comparisons.

138 lines (137 loc) 5.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.diffling = void 0; const diff_1 = require("diff"); const getLines = (value) => { if (value === "") return []; const lines = value.replace(/\n$/, "").split("\n"); return lines; }; const getDiff = (original, modified) => { const changes = (0, diff_1.diffChars)(original, modified); const diffs = { left: [], right: [] }; changes.forEach((change) => { var _a, _b, _c, _d; const { added, removed, value } = change; const diff = {}; if (added) { diff.type = "added"; diff.value = value; (_a = diffs.right) === null || _a === void 0 ? void 0 : _a.push(diff); } if (removed) { diff.type = "removed"; diff.value = value; (_b = diffs.left) === null || _b === void 0 ? void 0 : _b.push(diff); } if (!removed && !added) { diff.type = "default"; diff.value = value; (_c = diffs.right) === null || _c === void 0 ? void 0 : _c.push(diff); (_d = diffs.left) === null || _d === void 0 ? void 0 : _d.push(diff); } return diff; }); return diffs; }; const getChanges = (original, modified) => { if (typeof original === "string" && typeof modified === "string") { return (0, diff_1.diffLines)(original, modified, { newlineIsToken: false, ignoreWhitespace: false, ignoreCase: false, }); } return (0, diff_1.diffJson)(original, modified); }; const diffling = (original, modified, offset = 0) => { let changes = getChanges(original, modified); let rightLineNumber = offset; let leftLineNumber = offset; let lineInformation = []; let counter = 0; const lineNumbers = []; const ignoredIndexes = []; const getLineInformation = (diffIndex, change, compareFirstLine) => { const { value, added, removed } = change; const lines = getLines(value); return lines .map((line, index) => { var _a; const left = {}; const right = {}; if (ignoredIndexes.includes(`${diffIndex}-${index}`) || (compareFirstLine && index !== 0)) { return undefined; } if (added || removed) { let hasChanged = true; if (removed) { leftLineNumber += 1; left.lineNumber = leftLineNumber; left.type = "removed"; left.value = line || " "; const nextDiff = changes[diffIndex + 1]; if (nextDiff && nextDiff.added) { const nextDiffLines = getLines(nextDiff.value)[index]; if (nextDiffLines) { const change = { value: nextDiffLines, added: true, removed: false, }; const nextDiffLineInfo = getLineInformation(diffIndex, change, true); const { value: rightValue, lineNumber, type, } = ((_a = nextDiffLineInfo[0]) === null || _a === void 0 ? void 0 : _a.right) || {}; ignoredIndexes.push(`${diffIndex + 1}-${index}`); right.lineNumber = lineNumber; if (left.value === rightValue) { hasChanged = false; right.type = "default"; left.type = "default"; right.value = rightValue; } else { right.type = type; const diff = getDiff(line, rightValue); right.value = diff.right; left.value = diff.left; } } } } else { rightLineNumber = rightLineNumber + 1; right.lineNumber = rightLineNumber; right.type = "added"; right.value = line; } if (hasChanged && !compareFirstLine && !lineNumbers.includes(counter)) { lineNumbers.push(counter); } } else { left.lineNumber = leftLineNumber + 1; left.type = "default"; left.value = line; right.lineNumber = rightLineNumber + 1; right.type = "default"; right.value = line; } if (!compareFirstLine) counter += 1; return { right, left }; }) .filter(Boolean); }; changes.forEach((change, index) => { lineInformation.push(...getLineInformation(index, change)); }); return { lines: lineInformation, diffs: lineNumbers, }; }; exports.diffling = diffling;