fix(nacos): normalize config diff line endings

This commit is contained in:
二丫讲梵 authored and GitHub committed 2026-07-27 22:52:31 +08:00
1 parent c8b4224587
commit ea26a64b25
2 files changed
+53 -27

No files matched your search

+34
View File
@@ -124,6 +124,12 @@ describe("nacosAdmin helpers", () => {
expect(diff.preview).toContain("+ c");
});
it("uses the same terminal newline semantics for diff summaries", () => {
expect(summarizeNacosConfigDiff("aa", "aa\nbb")).toMatchObject({ changed: true, addedLines: 1, removedLines: 0 });
expect(summarizeNacosConfigDiff("aa", "aa\n")).toEqual({ changed: false, addedLines: 0, removedLines: 0, preview: "No content changes." });
expect(summarizeNacosConfigDiff("aa\r\n", "aa\n")).toEqual({ changed: false, addedLines: 0, removedLines: 0, preview: "No content changes." });
});
it("builds side-by-side config diff rows with inline segments", () => {
const rows = buildNacosSideBySideDiff('cloud:\n secret: "aaa"\n', 'cloud:\n secret: "aaa1"\n enabled: true\n');
expect(rows[0]).toMatchObject({ leftLineNumber: 1, rightLineNumber: 1, leftType: "equal", rightType: "equal" });
@@ -132,6 +138,34 @@ describe("nacosAdmin helpers", () => {
expect(rows[2]).toMatchObject({ leftLineNumber: null, rightLineNumber: 3, leftType: "padding", rightType: "insert" });
});
it("keeps unchanged lines when appending without a trailing newline", () => {
const rows = buildNacosSideBySideDiff("aa", "aa\nbb");
expect(rows).toHaveLength(2);
expect(rows[0]).toMatchObject({ leftLineNumber: 1, rightLineNumber: 1, leftContent: "aa", rightContent: "aa", leftType: "equal", rightType: "equal" });
expect(rows[1]).toMatchObject({ leftLineNumber: null, rightLineNumber: 2, leftContent: "", rightContent: "bb", leftType: "padding", rightType: "insert" });
const inlineRows = buildNacosInlineDiff("aa", "aa\nbb");
expect(inlineRows).toMatchObject([
{ lineNumber: 1, content: "aa", type: "equal" },
{ lineNumber: 2, content: "bb", type: "insert" },
]);
expect(inlineRows.some((row) => row.type === "delete")).toBe(false);
});
it("normalizes line endings and ignores terminal newline-only differences", () => {
expect(buildNacosSideBySideDiff("aa\n", "aa\nbb\n")).toMatchObject([
{ leftContent: "aa", rightContent: "aa", leftType: "equal", rightType: "equal" },
{ leftLineNumber: null, rightContent: "bb", leftType: "padding", rightType: "insert" },
]);
expect(buildNacosSideBySideDiff("aa\r\n", "aa\n")).toMatchObject([{ leftContent: "aa", rightContent: "aa", leftType: "equal", rightType: "equal" }]);
expect(buildNacosSideBySideDiff("aa\n", "aa")).toMatchObject([{ leftContent: "aa", rightContent: "aa", leftType: "equal", rightType: "equal" }]);
});
it("handles empty config content as line insertions", () => {
expect(buildNacosSideBySideDiff("", "bb")).toMatchObject([{ leftLineNumber: null, rightLineNumber: 1, rightContent: "bb", leftType: "padding", rightType: "insert" }]);
expect(buildNacosSideBySideDiff("", "")).toEqual([]);
});
it("builds inline config diff rows with character-level changed segments", () => {
const rows = buildNacosInlineDiff('secretId: "aaa1"\n', 'secretId: "aaa2"\n');
expect(rows).toHaveLength(2);
+19 -27
View File
@@ -1,5 +1,5 @@
import type { NacosConfigHistoryItem, NacosConfigItem, NacosConfigKey, NacosContentMatch, NacosImplementation, NacosInstanceInfo, NacosRawRequest, NacosServiceInfo, NacosVersionMode } from "@/types/nacos";
import { diffChars, diffLines } from "diff";
import { diffArrays, diffChars } from "diff";
export type NacosRawTemplateKey = "serverState" | "namespaceList" | "configDetail" | "serviceList" | "instanceList";
@@ -502,32 +502,24 @@ export interface NacosInlineDiffRow {
}
export function summarizeNacosConfigDiff(before: string, after: string, maxPreviewLines = 40): NacosDiffSummary {
if (before === after) {
return { changed: false, addedLines: 0, removedLines: 0, preview: "No content changes." };
}
const beforeLines = before.split(/\r?\n/);
const afterLines = after.split(/\r?\n/);
const max = Math.max(beforeLines.length, afterLines.length);
const changes = diffArrays(splitDiffLines(before), splitDiffLines(after));
const lines: string[] = [];
let addedLines = 0;
let removedLines = 0;
for (let index = 0; index < max; index += 1) {
const left = beforeLines[index];
const right = afterLines[index];
if (left === right) continue;
if (left !== undefined) {
removedLines += 1;
lines.push(`- ${left}`);
}
if (right !== undefined) {
addedLines += 1;
lines.push(`+ ${right}`);
}
if (lines.length >= maxPreviewLines) {
lines.push("...");
break;
for (const change of changes) {
if (!change.added && !change.removed) continue;
const prefix = change.added ? "+" : "-";
for (const line of change.value) {
if (change.added) addedLines += 1;
else removedLines += 1;
if (lines.length < maxPreviewLines) lines.push(`${prefix} ${line}`);
}
}
const changed = addedLines > 0 || removedLines > 0;
if (!changed) return { changed: false, addedLines: 0, removedLines: 0, preview: "No content changes." };
if (lines.length < addedLines + removedLines) lines.push("...");
return { changed: true, addedLines, removedLines, preview: lines.join("\n") };
}
@@ -581,7 +573,7 @@ function pairChangedLines(leftLines: string[], rightLines: string[], leftStart:
}
export function buildNacosSideBySideDiff(before: string, after: string): NacosSideBySideDiffRow[] {
const changes = diffLines(normalizeNacosDiffText(before), normalizeNacosDiffText(after), { newlineIsToken: false });
const changes = diffArrays(splitDiffLines(before), splitDiffLines(after));
const rows: NacosSideBySideDiffRow[] = [];
let leftLineNumber = 1;
let rightLineNumber = 1;
@@ -591,7 +583,7 @@ export function buildNacosSideBySideDiff(before: string, after: string): NacosSi
for (let index = 0; index < changes.length; index += 1) {
const change = changes[index];
if (!change.added && !change.removed) {
for (const line of splitDiffLines(change.value)) {
for (const line of change.value) {
rows.push({
id: nextId(),
leftLineNumber,
@@ -610,10 +602,10 @@ export function buildNacosSideBySideDiff(before: string, after: string): NacosSi
}
if (change.removed) {
const leftLines = splitDiffLines(change.value);
const leftLines = change.value;
const next = changes[index + 1];
if (next?.added) {
const rightLines = splitDiffLines(next.value);
const rightLines = next.value;
pairChangedLines(leftLines, rightLines, leftLineNumber, rightLineNumber, rows, nextId);
leftLineNumber += leftLines.length;
rightLineNumber += rightLines.length;
@@ -626,7 +618,7 @@ export function buildNacosSideBySideDiff(before: string, after: string): NacosSi
}
if (change.added) {
const rightLines = splitDiffLines(change.value);
const rightLines = change.value;
pairChangedLines([], rightLines, leftLineNumber, rightLineNumber, rows, nextId);
rightLineNumber += rightLines.length;
}