diff-leven 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.js +18 -446
- package/dist/index.mjs +18 -407
- package/package.json +6 -5
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
- Strings (character-level differences)
|
|
18
18
|
- Numbers, Booleans, and any serializable value
|
|
19
19
|
- **Rich Output Options**:
|
|
20
|
-
|
|
21
|
-
- Git-style diff format with clear additions/removals
|
|
20
|
+
|
|
21
|
+
- Git-style colorized output diff format with clear additions/removals
|
|
22
|
+
|
|
22
23
|
- **Flexible Configuration**:
|
|
23
24
|
- `color`: Toggle color output (default: `true`)
|
|
24
25
|
- `keysOnly`: Compare only object structure/keys (default: `false`)
|
package/dist/index.js
CHANGED
|
@@ -1,446 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/index.ts
|
|
31
|
-
var index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
DiffType: () => DiffType,
|
|
34
|
-
diff: () => diff,
|
|
35
|
-
diffRaw: () => diffRaw
|
|
36
|
-
});
|
|
37
|
-
module.exports = __toCommonJS(index_exports);
|
|
38
|
-
|
|
39
|
-
// src/diff.ts
|
|
40
|
-
var import_leven = __toESM(require("leven"));
|
|
41
|
-
|
|
42
|
-
// src/types.ts
|
|
43
|
-
var DiffType = /* @__PURE__ */ ((DiffType2) => {
|
|
44
|
-
DiffType2["ADDED"] = "added";
|
|
45
|
-
DiffType2["REMOVED"] = "removed";
|
|
46
|
-
DiffType2["CHANGED"] = "changed";
|
|
47
|
-
DiffType2["UNCHANGED"] = "unchanged";
|
|
48
|
-
return DiffType2;
|
|
49
|
-
})(DiffType || {});
|
|
50
|
-
|
|
51
|
-
// src/diff.ts
|
|
52
|
-
function createDiff(oldValue, newValue, options = {}, path = []) {
|
|
53
|
-
const { keysOnly = false, ignoreValues = false } = options;
|
|
54
|
-
if (oldValue === void 0 && newValue === void 0) {
|
|
55
|
-
return { type: "unchanged" /* UNCHANGED */ };
|
|
56
|
-
}
|
|
57
|
-
if (oldValue === void 0) {
|
|
58
|
-
return { type: "added" /* ADDED */, path, newValue };
|
|
59
|
-
}
|
|
60
|
-
if (newValue === void 0) {
|
|
61
|
-
return { type: "removed" /* REMOVED */, path, oldValue };
|
|
62
|
-
}
|
|
63
|
-
if (typeof oldValue !== "object" || typeof newValue !== "object" || oldValue === null || newValue === null) {
|
|
64
|
-
if (keysOnly || ignoreValues) {
|
|
65
|
-
return {
|
|
66
|
-
type: "unchanged" /* UNCHANGED */,
|
|
67
|
-
path,
|
|
68
|
-
oldValue,
|
|
69
|
-
newValue,
|
|
70
|
-
meta: { ignored: true }
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
if (oldValue === newValue) {
|
|
74
|
-
return { type: "unchanged" /* UNCHANGED */, path, oldValue, newValue };
|
|
75
|
-
}
|
|
76
|
-
if (typeof oldValue === "string" && typeof newValue === "string") {
|
|
77
|
-
const distance = (0, import_leven.default)(oldValue, newValue);
|
|
78
|
-
const maxLength = Math.max(oldValue.length, newValue.length);
|
|
79
|
-
const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;
|
|
80
|
-
return {
|
|
81
|
-
type: "changed" /* CHANGED */,
|
|
82
|
-
path,
|
|
83
|
-
oldValue,
|
|
84
|
-
newValue,
|
|
85
|
-
meta: {
|
|
86
|
-
levenDistance: distance,
|
|
87
|
-
similarity: similarityRatio
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
return { type: "changed" /* CHANGED */, path, oldValue, newValue };
|
|
92
|
-
}
|
|
93
|
-
if (Array.isArray(oldValue) && Array.isArray(newValue)) {
|
|
94
|
-
return compareArrays(oldValue, newValue, options, path);
|
|
95
|
-
}
|
|
96
|
-
return compareObjects(
|
|
97
|
-
oldValue,
|
|
98
|
-
newValue,
|
|
99
|
-
options,
|
|
100
|
-
path
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
function compareObjects(oldObj, newObj, options, path) {
|
|
104
|
-
const { ignoreKeys = [] } = options;
|
|
105
|
-
const allKeys = /* @__PURE__ */ new Set([
|
|
106
|
-
...Object.keys(oldObj).filter((key) => !ignoreKeys.includes(key)),
|
|
107
|
-
...Object.keys(newObj).filter((key) => !ignoreKeys.includes(key))
|
|
108
|
-
]);
|
|
109
|
-
const children = [];
|
|
110
|
-
let hasChanges = false;
|
|
111
|
-
for (const key of allKeys) {
|
|
112
|
-
const childPath = [...path, key];
|
|
113
|
-
const oldValue = oldObj[key];
|
|
114
|
-
const newValue = newObj[key];
|
|
115
|
-
const childDiff = createDiff(oldValue, newValue, options, childPath);
|
|
116
|
-
if (childDiff.type !== "unchanged" /* UNCHANGED */) {
|
|
117
|
-
hasChanges = true;
|
|
118
|
-
}
|
|
119
|
-
children.push(childDiff);
|
|
120
|
-
}
|
|
121
|
-
if (hasChanges) {
|
|
122
|
-
return {
|
|
123
|
-
type: "changed" /* CHANGED */,
|
|
124
|
-
path,
|
|
125
|
-
oldValue: oldObj,
|
|
126
|
-
newValue: newObj,
|
|
127
|
-
children
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
return { type: "unchanged" /* UNCHANGED */, path, oldValue: oldObj, newValue: newObj };
|
|
131
|
-
}
|
|
132
|
-
function compareArrays(oldArray, newArray, options, path) {
|
|
133
|
-
if (oldArray.length !== newArray.length) {
|
|
134
|
-
const children2 = [];
|
|
135
|
-
const maxLength = Math.max(oldArray.length, newArray.length);
|
|
136
|
-
for (let i = 0; i < maxLength; i++) {
|
|
137
|
-
const childPath = [...path, i.toString()];
|
|
138
|
-
if (i >= oldArray.length) {
|
|
139
|
-
children2.push({
|
|
140
|
-
type: "added" /* ADDED */,
|
|
141
|
-
path: childPath,
|
|
142
|
-
newValue: newArray[i]
|
|
143
|
-
});
|
|
144
|
-
} else if (i >= newArray.length) {
|
|
145
|
-
children2.push({
|
|
146
|
-
type: "removed" /* REMOVED */,
|
|
147
|
-
path: childPath,
|
|
148
|
-
oldValue: oldArray[i]
|
|
149
|
-
});
|
|
150
|
-
} else {
|
|
151
|
-
children2.push(createDiff(oldArray[i], newArray[i], options, childPath));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
type: "changed" /* CHANGED */,
|
|
156
|
-
path,
|
|
157
|
-
oldValue: oldArray,
|
|
158
|
-
newValue: newArray,
|
|
159
|
-
children: children2
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
const children = [];
|
|
163
|
-
let hasChanges = false;
|
|
164
|
-
for (let i = 0; i < oldArray.length; i++) {
|
|
165
|
-
const childPath = [...path, i.toString()];
|
|
166
|
-
const oldValue = oldArray[i];
|
|
167
|
-
const newValue = newArray[i];
|
|
168
|
-
let childDiff;
|
|
169
|
-
if (typeof oldValue === "string" && typeof newValue === "string") {
|
|
170
|
-
if (oldValue === newValue) {
|
|
171
|
-
childDiff = {
|
|
172
|
-
type: "unchanged" /* UNCHANGED */,
|
|
173
|
-
path: childPath,
|
|
174
|
-
oldValue,
|
|
175
|
-
newValue
|
|
176
|
-
};
|
|
177
|
-
} else {
|
|
178
|
-
const distance = (0, import_leven.default)(oldValue, newValue);
|
|
179
|
-
const maxLength = Math.max(oldValue.length, newValue.length);
|
|
180
|
-
const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;
|
|
181
|
-
childDiff = {
|
|
182
|
-
type: "changed" /* CHANGED */,
|
|
183
|
-
path: childPath,
|
|
184
|
-
oldValue,
|
|
185
|
-
newValue,
|
|
186
|
-
meta: {
|
|
187
|
-
levenDistance: distance,
|
|
188
|
-
similarity: similarityRatio
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
hasChanges = true;
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
childDiff = createDiff(oldValue, newValue, options, childPath);
|
|
195
|
-
if (childDiff.type !== "unchanged" /* UNCHANGED */) {
|
|
196
|
-
hasChanges = true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
children.push(childDiff);
|
|
200
|
-
}
|
|
201
|
-
if (hasChanges) {
|
|
202
|
-
return {
|
|
203
|
-
type: "changed" /* CHANGED */,
|
|
204
|
-
path,
|
|
205
|
-
oldValue: oldArray,
|
|
206
|
-
newValue: newArray,
|
|
207
|
-
children
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
return {
|
|
211
|
-
type: "unchanged" /* UNCHANGED */,
|
|
212
|
-
path,
|
|
213
|
-
oldValue: oldArray,
|
|
214
|
-
newValue: newArray
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// src/formatter.ts
|
|
219
|
-
var colors = {
|
|
220
|
-
reset: "\x1B[0m",
|
|
221
|
-
red: "\x1B[31m",
|
|
222
|
-
green: "\x1B[32m",
|
|
223
|
-
gray: "\x1B[90m"
|
|
224
|
-
};
|
|
225
|
-
function formatDiff(diff2, options = {}) {
|
|
226
|
-
const { color = true, full = false } = options;
|
|
227
|
-
if (diff2.type === "unchanged" /* UNCHANGED */ && !full && (!diff2.children || diff2.children.length === 0)) {
|
|
228
|
-
return "";
|
|
229
|
-
}
|
|
230
|
-
if (!diff2.children || diff2.children.length === 0) {
|
|
231
|
-
return formatValue(diff2, color);
|
|
232
|
-
}
|
|
233
|
-
return formatComplex(diff2, options, 0);
|
|
234
|
-
}
|
|
235
|
-
function formatValue(diff2, useColor) {
|
|
236
|
-
const prefix = getPrefix(diff2.type);
|
|
237
|
-
let value = "";
|
|
238
|
-
switch (diff2.type) {
|
|
239
|
-
case "added" /* ADDED */:
|
|
240
|
-
value = formatPrimitive(diff2.newValue);
|
|
241
|
-
return useColor ? `${colors.green}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
242
|
-
case "removed" /* REMOVED */:
|
|
243
|
-
value = formatPrimitive(diff2.oldValue);
|
|
244
|
-
return useColor ? `${colors.red}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
245
|
-
case "changed" /* CHANGED */:
|
|
246
|
-
const oldVal = formatPrimitive(diff2.oldValue);
|
|
247
|
-
const newVal = formatPrimitive(diff2.newValue);
|
|
248
|
-
let similarityInfo = "";
|
|
249
|
-
if (diff2.meta?.similarity !== void 0 && typeof diff2.oldValue === "string" && typeof diff2.newValue === "string") {
|
|
250
|
-
const similarity = Math.round(diff2.meta.similarity * 100);
|
|
251
|
-
similarityInfo = useColor ? `${colors.gray} (${similarity}% similar)${colors.reset}` : ` (${similarity}% similar)`;
|
|
252
|
-
}
|
|
253
|
-
const oldLine = useColor ? `${colors.red}- ${oldVal}${colors.reset}` : `- ${oldVal}`;
|
|
254
|
-
const newLine = useColor ? `${colors.green}+ ${newVal}${similarityInfo}${colors.reset}` : `+ ${newVal}${similarityInfo}`;
|
|
255
|
-
return `${oldLine}
|
|
256
|
-
${newLine}`;
|
|
257
|
-
default:
|
|
258
|
-
value = formatPrimitive(diff2.newValue ?? diff2.oldValue);
|
|
259
|
-
return useColor ? `${colors.gray}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
function formatComplex(diff2, options, indent = 0) {
|
|
263
|
-
const { full = false } = options;
|
|
264
|
-
if (diff2.type === "unchanged" /* UNCHANGED */ && !full && (!diff2.children || diff2.children.length === 0 || typeof diff2.oldValue !== "object" && typeof diff2.newValue !== "object")) {
|
|
265
|
-
return "";
|
|
266
|
-
}
|
|
267
|
-
return Array.isArray(diff2.oldValue) || Array.isArray(diff2.newValue) ? formatArrayDiff(diff2, options, indent) : formatObjectDiff(diff2, options, indent);
|
|
268
|
-
}
|
|
269
|
-
function formatArrayDiff(diff2, options, indent = 0) {
|
|
270
|
-
const { color = true, full = false } = options;
|
|
271
|
-
const baseIndent = " ".repeat(indent);
|
|
272
|
-
const innerIndent = " ".repeat(indent + 2);
|
|
273
|
-
let result = `[
|
|
274
|
-
`;
|
|
275
|
-
let visibleItems = 0;
|
|
276
|
-
if (diff2.children) {
|
|
277
|
-
for (let i = 0; i < diff2.children.length; i++) {
|
|
278
|
-
const child = diff2.children[i];
|
|
279
|
-
if (child.type === "unchanged" /* UNCHANGED */ && !full && (!child.children || child.children.length === 0)) {
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
if (child.children && child.children.length > 0) {
|
|
283
|
-
const nestedOutput = Array.isArray(child.newValue || child.oldValue) ? formatArrayDiff(child, options, indent + 2) : formatObjectDiff(child, options, indent + 2);
|
|
284
|
-
if (nestedOutput.trim().length > 2) {
|
|
285
|
-
if (visibleItems > 0) {
|
|
286
|
-
result += ",\n";
|
|
287
|
-
}
|
|
288
|
-
result += innerIndent;
|
|
289
|
-
result += nestedOutput;
|
|
290
|
-
visibleItems++;
|
|
291
|
-
}
|
|
292
|
-
} else {
|
|
293
|
-
if (visibleItems > 0) {
|
|
294
|
-
result += ",\n";
|
|
295
|
-
}
|
|
296
|
-
switch (child.type) {
|
|
297
|
-
case "added" /* ADDED */:
|
|
298
|
-
result += color ? `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}+ ${formatPrimitive(child.newValue)}`;
|
|
299
|
-
visibleItems++;
|
|
300
|
-
break;
|
|
301
|
-
case "removed" /* REMOVED */:
|
|
302
|
-
result += color ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}` : `${innerIndent}- ${formatPrimitive(child.oldValue)}`;
|
|
303
|
-
visibleItems++;
|
|
304
|
-
break;
|
|
305
|
-
case "unchanged" /* UNCHANGED */:
|
|
306
|
-
if (child.meta?.ignored && child.path) {
|
|
307
|
-
result += color ? `${innerIndent}${colors.gray} ${child.path[child.path.length - 1] || ""}${colors.reset}` : `${innerIndent} ${child.path[child.path.length - 1] || ""}`;
|
|
308
|
-
} else {
|
|
309
|
-
result += color ? `${innerIndent}${colors.gray} ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent} ${formatPrimitive(child.newValue)}`;
|
|
310
|
-
}
|
|
311
|
-
visibleItems++;
|
|
312
|
-
break;
|
|
313
|
-
case "changed" /* CHANGED */:
|
|
314
|
-
result += color ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}
|
|
315
|
-
${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}- ${formatPrimitive(child.oldValue)}
|
|
316
|
-
${innerIndent}+ ${formatPrimitive(child.newValue)}`;
|
|
317
|
-
visibleItems++;
|
|
318
|
-
break;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
if (visibleItems > 0) {
|
|
324
|
-
result += "\n";
|
|
325
|
-
}
|
|
326
|
-
result += `${baseIndent}]`;
|
|
327
|
-
return result;
|
|
328
|
-
}
|
|
329
|
-
function formatObjectDiff(diff2, options, indent = 0) {
|
|
330
|
-
const { color = true, full = false } = options;
|
|
331
|
-
const baseIndent = " ".repeat(indent);
|
|
332
|
-
const innerIndent = " ".repeat(indent + 2);
|
|
333
|
-
let result = `{
|
|
334
|
-
`;
|
|
335
|
-
let visibleItems = 0;
|
|
336
|
-
if (diff2.children) {
|
|
337
|
-
const displayableChildren = diff2.children.filter((child) => {
|
|
338
|
-
if (child.type !== "unchanged" /* UNCHANGED */) return true;
|
|
339
|
-
if (full) return true;
|
|
340
|
-
if (child.children && child.children.length > 0) return true;
|
|
341
|
-
const key = child.path?.[child.path.length - 1] || "";
|
|
342
|
-
if (options.outputKeys?.includes(key)) return true;
|
|
343
|
-
return false;
|
|
344
|
-
});
|
|
345
|
-
for (let i = 0; i < displayableChildren.length; i++) {
|
|
346
|
-
const child = displayableChildren[i];
|
|
347
|
-
const key = child.path?.[child.path.length - 1] || "";
|
|
348
|
-
const isLast = i === displayableChildren.length - 1;
|
|
349
|
-
if (visibleItems > 0 && !result.endsWith("\n")) {
|
|
350
|
-
result += ",\n";
|
|
351
|
-
}
|
|
352
|
-
if (child.children && child.children.length > 0) {
|
|
353
|
-
const nestedContent = Array.isArray(child.newValue || child.oldValue) ? formatArrayDiff(child, options, indent + 2) : formatObjectDiff(child, options, indent + 2);
|
|
354
|
-
if (nestedContent.trim().length > 2) {
|
|
355
|
-
result += `${innerIndent}${key}: ${nestedContent}`;
|
|
356
|
-
visibleItems++;
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
switch (child.type) {
|
|
360
|
-
case "added" /* ADDED */:
|
|
361
|
-
result += color ? `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;
|
|
362
|
-
visibleItems++;
|
|
363
|
-
break;
|
|
364
|
-
case "removed" /* REMOVED */:
|
|
365
|
-
result += color ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}` : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}`;
|
|
366
|
-
visibleItems++;
|
|
367
|
-
break;
|
|
368
|
-
case "changed" /* CHANGED */:
|
|
369
|
-
result += color ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}
|
|
370
|
-
${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}
|
|
371
|
-
${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;
|
|
372
|
-
visibleItems++;
|
|
373
|
-
break;
|
|
374
|
-
case "unchanged" /* UNCHANGED */:
|
|
375
|
-
if (full || options.outputKeys?.includes(key)) {
|
|
376
|
-
if (child.meta?.ignored) {
|
|
377
|
-
result += color ? `${innerIndent}${colors.gray} ${key}${colors.reset}` : `${innerIndent} ${key}`;
|
|
378
|
-
} else {
|
|
379
|
-
result += color ? `${innerIndent}${colors.gray} ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent} ${key}: ${formatPrimitive(child.newValue)}`;
|
|
380
|
-
}
|
|
381
|
-
visibleItems++;
|
|
382
|
-
}
|
|
383
|
-
break;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
if (!isLast && !result.endsWith("\n")) {
|
|
387
|
-
result += ",";
|
|
388
|
-
}
|
|
389
|
-
if (!result.endsWith("\n")) {
|
|
390
|
-
result += "\n";
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
if (visibleItems > 0 && !result.endsWith("\n")) {
|
|
395
|
-
result += "\n";
|
|
396
|
-
}
|
|
397
|
-
result += `${baseIndent}}`;
|
|
398
|
-
return result;
|
|
399
|
-
}
|
|
400
|
-
function getPrefix(type) {
|
|
401
|
-
switch (type) {
|
|
402
|
-
case "added" /* ADDED */:
|
|
403
|
-
return "+";
|
|
404
|
-
case "removed" /* REMOVED */:
|
|
405
|
-
return "-";
|
|
406
|
-
case "changed" /* CHANGED */:
|
|
407
|
-
return "!";
|
|
408
|
-
default:
|
|
409
|
-
return " ";
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
function formatPrimitive(value) {
|
|
413
|
-
if (value === void 0) {
|
|
414
|
-
return "undefined";
|
|
415
|
-
}
|
|
416
|
-
if (value === null) {
|
|
417
|
-
return "null";
|
|
418
|
-
}
|
|
419
|
-
if (typeof value === "string") {
|
|
420
|
-
return `'${value}'`;
|
|
421
|
-
}
|
|
422
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
423
|
-
return value.toString();
|
|
424
|
-
}
|
|
425
|
-
if (typeof value === "object") {
|
|
426
|
-
const json = JSON.stringify(value, null, 2);
|
|
427
|
-
return json;
|
|
428
|
-
}
|
|
429
|
-
return String(value);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// src/index.ts
|
|
433
|
-
function diffRaw(oldValue, newValue, options = {}) {
|
|
434
|
-
return createDiff(oldValue, newValue, options);
|
|
435
|
-
}
|
|
436
|
-
function diff(oldValue, newValue, options = {}) {
|
|
437
|
-
const diffResult = diffRaw(oldValue, newValue, options);
|
|
438
|
-
return formatDiff(diffResult, options);
|
|
439
|
-
}
|
|
440
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
441
|
-
0 && (module.exports = {
|
|
442
|
-
DiffType,
|
|
443
|
-
diff,
|
|
444
|
-
diffRaw
|
|
445
|
-
});
|
|
446
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _leven = require('leven'); var _leven2 = _interopRequireDefault(_leven);var h=($=>($.ADDED="added",$.REMOVED="removed",$.CHANGED="changed",$.UNCHANGED="unchanged",$))(h||{});function y(e,t,a={},r=[]){let{keysOnly:$=!1,ignoreValues:g=!1}=a;if(e===void 0&&t===void 0)return{type:"unchanged"};if(e===void 0)return{type:"added",path:r,newValue:t};if(t===void 0)return{type:"removed",path:r,oldValue:e};if(typeof e!="object"||typeof t!="object"||e===null||t===null){if($||g)return{type:"unchanged",path:r,oldValue:e,newValue:t,meta:{ignored:!0}};if(e===t)return{type:"unchanged",path:r,oldValue:e,newValue:t};if(typeof e=="string"&&typeof t=="string"){let n=_leven2.default.call(void 0, e,t),s=Math.max(e.length,t.length),i=s>0?1-n/s:1;return{type:"changed",path:r,oldValue:e,newValue:t,meta:{levenDistance:n,similarity:i}}}return{type:"changed",path:r,oldValue:e,newValue:t}}return Array.isArray(e)&&Array.isArray(t)?R(e,t,a,r):N(e,t,a,r)}function N(e,t,a,r){let{ignoreKeys:$=[]}=a,g=new Set([...Object.keys(e).filter(i=>!$.includes(i)),...Object.keys(t).filter(i=>!$.includes(i))]),n=[],s=!1;for(let i of g){let c=[...r,i],l=e[i],f=t[i],D=y(l,f,a,c);D.type!=="unchanged"&&(s=!0),n.push(D)}return s?{type:"changed",path:r,oldValue:e,newValue:t,children:n}:{type:"unchanged",path:r,oldValue:e,newValue:t}}function R(e,t,a,r){if(e.length!==t.length){let n=[],s=Math.max(e.length,t.length);for(let i=0;i<s;i++){let c=[...r,i.toString()];i>=e.length?n.push({type:"added",path:c,newValue:t[i]}):i>=t.length?n.push({type:"removed",path:c,oldValue:e[i]}):n.push(y(e[i],t[i],a,c))}return{type:"changed",path:r,oldValue:e,newValue:t,children:n}}let $=[],g=!1;for(let n=0;n<e.length;n++){let s=[...r,n.toString()],i=e[n],c=t[n],l;if(typeof i=="string"&&typeof c=="string")if(i===c)l={type:"unchanged",path:s,oldValue:i,newValue:c};else{let f=_leven2.default.call(void 0, i,c),D=Math.max(i.length,c.length),p=D>0?1-f/D:1;l={type:"changed",path:s,oldValue:i,newValue:c,meta:{levenDistance:f,similarity:p}},g=!0}else l=y(i,c,a,s),l.type!=="unchanged"&&(g=!0);$.push(l)}return g?{type:"changed",path:r,oldValue:e,newValue:t,children:$}:{type:"unchanged",path:r,oldValue:e,newValue:t}}var u={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",gray:"\x1B[90m"};function b(e,t={}){let{color:a=!0,full:r=!1}=t;return e.type==="unchanged"&&!r&&(!e.children||e.children.length===0)?"":!e.children||e.children.length===0?A(e,a):C(e,t,0)}function A(e,t){let a=G(e.type),r="";switch(e.type){case"added":return r=o(e.newValue),t?`${u.green}${a} ${r}${u.reset}`:`${a} ${r}`;case"removed":return r=o(e.oldValue),t?`${u.red}${a} ${r}${u.reset}`:`${a} ${r}`;case"changed":let $=o(e.oldValue),g=o(e.newValue),n="";if(_optionalChain([e, 'access', _ => _.meta, 'optionalAccess', _2 => _2.similarity])!==void 0&&typeof e.oldValue=="string"&&typeof e.newValue=="string"){let c=Math.round(e.meta.similarity*100);n=t?`${u.gray} (${c}% similar)${u.reset}`:` (${c}% similar)`}let s=t?`${u.red}- ${$}${u.reset}`:`- ${$}`,i=t?`${u.green}+ ${g}${n}${u.reset}`:`+ ${g}${n}`;return`${s}
|
|
2
|
+
${i}`;default:return r=o(_nullishCoalesce(e.newValue, () => (e.oldValue))),t?`${u.gray}${a} ${r}${u.reset}`:`${a} ${r}`}}function C(e,t,a=0){let{full:r=!1}=t;return e.type==="unchanged"&&!r&&(!e.children||e.children.length===0||typeof e.oldValue!="object"&&typeof e.newValue!="object")?"":Array.isArray(e.oldValue)||Array.isArray(e.newValue)?m(e,t,a):d(e,t,a)}function m(e,t,a=0){let{color:r=!0,full:$=!1}=t,g=" ".repeat(a),n=" ".repeat(a+2),s=`[
|
|
3
|
+
`,i=0;if(e.children)for(let c=0;c<e.children.length;c++){let l=e.children[c];if(!(l.type==="unchanged"&&!$&&(!l.children||l.children.length===0)))if(l.children&&l.children.length>0){let f=Array.isArray(l.newValue||l.oldValue)?m(l,t,a+2):d(l,t,a+2);f.trim().length>2&&(i>0&&(s+=`,
|
|
4
|
+
`),s+=n,s+=f,i++)}else switch(i>0&&(s+=`,
|
|
5
|
+
`),l.type){case"added":s+=r?`${n}${u.green}+ ${o(l.newValue)}${u.reset}`:`${n}+ ${o(l.newValue)}`,i++;break;case"removed":s+=r?`${n}${u.red}- ${o(l.oldValue)}${u.reset}`:`${n}- ${o(l.oldValue)}`,i++;break;case"unchanged":_optionalChain([l, 'access', _3 => _3.meta, 'optionalAccess', _4 => _4.ignored])&&l.path?s+=r?`${n}${u.gray} ${l.path[l.path.length-1]||""}${u.reset}`:`${n} ${l.path[l.path.length-1]||""}`:s+=r?`${n}${u.gray} ${o(l.newValue)}${u.reset}`:`${n} ${o(l.newValue)}`,i++;break;case"changed":s+=r?`${n}${u.red}- ${o(l.oldValue)}${u.reset}
|
|
6
|
+
${n}${u.green}+ ${o(l.newValue)}${u.reset}`:`${n}- ${o(l.oldValue)}
|
|
7
|
+
${n}+ ${o(l.newValue)}`,i++;break}}return i>0&&(s+=`
|
|
8
|
+
`),s+=`${g}]`,s}function d(e,t,a=0){let{color:r=!0,full:$=!1}=t,g=" ".repeat(a),n=" ".repeat(a+2),s=`{
|
|
9
|
+
`,i=0;if(e.children){let c=e.children.filter(l=>{if(l.type!=="unchanged"||$||l.children&&l.children.length>0)return!0;let f=_optionalChain([l, 'access', _5 => _5.path, 'optionalAccess', _6 => _6[l.path.length-1]])||"";return!!_optionalChain([t, 'access', _7 => _7.outputKeys, 'optionalAccess', _8 => _8.includes, 'call', _9 => _9(f)])});for(let l=0;l<c.length;l++){let f=c[l],D=_optionalChain([f, 'access', _10 => _10.path, 'optionalAccess', _11 => _11[f.path.length-1]])||"",p=l===c.length-1;if(i>0&&!s.endsWith(`
|
|
10
|
+
`)&&(s+=`,
|
|
11
|
+
`),f.children&&f.children.length>0){let V=Array.isArray(f.newValue||f.oldValue)?m(f,t,a+2):d(f,t,a+2);V.trim().length>2&&(s+=`${n}${D}: ${V}`,i++)}else switch(f.type){case"added":s+=r?`${n}${u.green}+ ${D}: ${o(f.newValue)}${u.reset}`:`${n}+ ${D}: ${o(f.newValue)}`,i++;break;case"removed":s+=r?`${n}${u.red}- ${D}: ${o(f.oldValue)}${u.reset}`:`${n}- ${D}: ${o(f.oldValue)}`,i++;break;case"changed":s+=r?`${n}${u.red}- ${D}: ${o(f.oldValue)}${u.reset}
|
|
12
|
+
${n}${u.green}+ ${D}: ${o(f.newValue)}${u.reset}`:`${n}- ${D}: ${o(f.oldValue)}
|
|
13
|
+
${n}+ ${D}: ${o(f.newValue)}`,i++;break;case"unchanged":($||_optionalChain([t, 'access', _12 => _12.outputKeys, 'optionalAccess', _13 => _13.includes, 'call', _14 => _14(D)]))&&(_optionalChain([f, 'access', _15 => _15.meta, 'optionalAccess', _16 => _16.ignored])?s+=r?`${n}${u.gray} ${D}${u.reset}`:`${n} ${D}`:s+=r?`${n}${u.gray} ${D}: ${o(f.newValue)}${u.reset}`:`${n} ${D}: ${o(f.newValue)}`,i++);break}!p&&!s.endsWith(`
|
|
14
|
+
`)&&(s+=","),s.endsWith(`
|
|
15
|
+
`)||(s+=`
|
|
16
|
+
`)}}return i>0&&!s.endsWith(`
|
|
17
|
+
`)&&(s+=`
|
|
18
|
+
`),s+=`${g}}`,s}function G(e){switch(e){case"added":return"+";case"removed":return"-";case"changed":return"!";default:return" "}}function o(e){return e===void 0?"undefined":e===null?"null":typeof e=="string"?`'${e}'`:typeof e=="number"||typeof e=="boolean"?e.toString():typeof e=="object"?JSON.stringify(e,null,2):String(e)}function H(e,t,a={}){return y(e,t,a)}function v(e,t,a={}){let r=H(e,t,a);return b(r,a)}exports.DiffType = h; exports.diff = v; exports.diffRaw = H;
|
package/dist/index.mjs
CHANGED
|
@@ -1,407 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
})(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (oldValue === void 0) {
|
|
20
|
-
return { type: "added" /* ADDED */, path, newValue };
|
|
21
|
-
}
|
|
22
|
-
if (newValue === void 0) {
|
|
23
|
-
return { type: "removed" /* REMOVED */, path, oldValue };
|
|
24
|
-
}
|
|
25
|
-
if (typeof oldValue !== "object" || typeof newValue !== "object" || oldValue === null || newValue === null) {
|
|
26
|
-
if (keysOnly || ignoreValues) {
|
|
27
|
-
return {
|
|
28
|
-
type: "unchanged" /* UNCHANGED */,
|
|
29
|
-
path,
|
|
30
|
-
oldValue,
|
|
31
|
-
newValue,
|
|
32
|
-
meta: { ignored: true }
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
if (oldValue === newValue) {
|
|
36
|
-
return { type: "unchanged" /* UNCHANGED */, path, oldValue, newValue };
|
|
37
|
-
}
|
|
38
|
-
if (typeof oldValue === "string" && typeof newValue === "string") {
|
|
39
|
-
const distance = leven(oldValue, newValue);
|
|
40
|
-
const maxLength = Math.max(oldValue.length, newValue.length);
|
|
41
|
-
const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;
|
|
42
|
-
return {
|
|
43
|
-
type: "changed" /* CHANGED */,
|
|
44
|
-
path,
|
|
45
|
-
oldValue,
|
|
46
|
-
newValue,
|
|
47
|
-
meta: {
|
|
48
|
-
levenDistance: distance,
|
|
49
|
-
similarity: similarityRatio
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
return { type: "changed" /* CHANGED */, path, oldValue, newValue };
|
|
54
|
-
}
|
|
55
|
-
if (Array.isArray(oldValue) && Array.isArray(newValue)) {
|
|
56
|
-
return compareArrays(oldValue, newValue, options, path);
|
|
57
|
-
}
|
|
58
|
-
return compareObjects(
|
|
59
|
-
oldValue,
|
|
60
|
-
newValue,
|
|
61
|
-
options,
|
|
62
|
-
path
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
function compareObjects(oldObj, newObj, options, path) {
|
|
66
|
-
const { ignoreKeys = [] } = options;
|
|
67
|
-
const allKeys = /* @__PURE__ */ new Set([
|
|
68
|
-
...Object.keys(oldObj).filter((key) => !ignoreKeys.includes(key)),
|
|
69
|
-
...Object.keys(newObj).filter((key) => !ignoreKeys.includes(key))
|
|
70
|
-
]);
|
|
71
|
-
const children = [];
|
|
72
|
-
let hasChanges = false;
|
|
73
|
-
for (const key of allKeys) {
|
|
74
|
-
const childPath = [...path, key];
|
|
75
|
-
const oldValue = oldObj[key];
|
|
76
|
-
const newValue = newObj[key];
|
|
77
|
-
const childDiff = createDiff(oldValue, newValue, options, childPath);
|
|
78
|
-
if (childDiff.type !== "unchanged" /* UNCHANGED */) {
|
|
79
|
-
hasChanges = true;
|
|
80
|
-
}
|
|
81
|
-
children.push(childDiff);
|
|
82
|
-
}
|
|
83
|
-
if (hasChanges) {
|
|
84
|
-
return {
|
|
85
|
-
type: "changed" /* CHANGED */,
|
|
86
|
-
path,
|
|
87
|
-
oldValue: oldObj,
|
|
88
|
-
newValue: newObj,
|
|
89
|
-
children
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return { type: "unchanged" /* UNCHANGED */, path, oldValue: oldObj, newValue: newObj };
|
|
93
|
-
}
|
|
94
|
-
function compareArrays(oldArray, newArray, options, path) {
|
|
95
|
-
if (oldArray.length !== newArray.length) {
|
|
96
|
-
const children2 = [];
|
|
97
|
-
const maxLength = Math.max(oldArray.length, newArray.length);
|
|
98
|
-
for (let i = 0; i < maxLength; i++) {
|
|
99
|
-
const childPath = [...path, i.toString()];
|
|
100
|
-
if (i >= oldArray.length) {
|
|
101
|
-
children2.push({
|
|
102
|
-
type: "added" /* ADDED */,
|
|
103
|
-
path: childPath,
|
|
104
|
-
newValue: newArray[i]
|
|
105
|
-
});
|
|
106
|
-
} else if (i >= newArray.length) {
|
|
107
|
-
children2.push({
|
|
108
|
-
type: "removed" /* REMOVED */,
|
|
109
|
-
path: childPath,
|
|
110
|
-
oldValue: oldArray[i]
|
|
111
|
-
});
|
|
112
|
-
} else {
|
|
113
|
-
children2.push(createDiff(oldArray[i], newArray[i], options, childPath));
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
type: "changed" /* CHANGED */,
|
|
118
|
-
path,
|
|
119
|
-
oldValue: oldArray,
|
|
120
|
-
newValue: newArray,
|
|
121
|
-
children: children2
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
const children = [];
|
|
125
|
-
let hasChanges = false;
|
|
126
|
-
for (let i = 0; i < oldArray.length; i++) {
|
|
127
|
-
const childPath = [...path, i.toString()];
|
|
128
|
-
const oldValue = oldArray[i];
|
|
129
|
-
const newValue = newArray[i];
|
|
130
|
-
let childDiff;
|
|
131
|
-
if (typeof oldValue === "string" && typeof newValue === "string") {
|
|
132
|
-
if (oldValue === newValue) {
|
|
133
|
-
childDiff = {
|
|
134
|
-
type: "unchanged" /* UNCHANGED */,
|
|
135
|
-
path: childPath,
|
|
136
|
-
oldValue,
|
|
137
|
-
newValue
|
|
138
|
-
};
|
|
139
|
-
} else {
|
|
140
|
-
const distance = leven(oldValue, newValue);
|
|
141
|
-
const maxLength = Math.max(oldValue.length, newValue.length);
|
|
142
|
-
const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;
|
|
143
|
-
childDiff = {
|
|
144
|
-
type: "changed" /* CHANGED */,
|
|
145
|
-
path: childPath,
|
|
146
|
-
oldValue,
|
|
147
|
-
newValue,
|
|
148
|
-
meta: {
|
|
149
|
-
levenDistance: distance,
|
|
150
|
-
similarity: similarityRatio
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
hasChanges = true;
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
childDiff = createDiff(oldValue, newValue, options, childPath);
|
|
157
|
-
if (childDiff.type !== "unchanged" /* UNCHANGED */) {
|
|
158
|
-
hasChanges = true;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
children.push(childDiff);
|
|
162
|
-
}
|
|
163
|
-
if (hasChanges) {
|
|
164
|
-
return {
|
|
165
|
-
type: "changed" /* CHANGED */,
|
|
166
|
-
path,
|
|
167
|
-
oldValue: oldArray,
|
|
168
|
-
newValue: newArray,
|
|
169
|
-
children
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
type: "unchanged" /* UNCHANGED */,
|
|
174
|
-
path,
|
|
175
|
-
oldValue: oldArray,
|
|
176
|
-
newValue: newArray
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// src/formatter.ts
|
|
181
|
-
var colors = {
|
|
182
|
-
reset: "\x1B[0m",
|
|
183
|
-
red: "\x1B[31m",
|
|
184
|
-
green: "\x1B[32m",
|
|
185
|
-
gray: "\x1B[90m"
|
|
186
|
-
};
|
|
187
|
-
function formatDiff(diff2, options = {}) {
|
|
188
|
-
const { color = true, full = false } = options;
|
|
189
|
-
if (diff2.type === "unchanged" /* UNCHANGED */ && !full && (!diff2.children || diff2.children.length === 0)) {
|
|
190
|
-
return "";
|
|
191
|
-
}
|
|
192
|
-
if (!diff2.children || diff2.children.length === 0) {
|
|
193
|
-
return formatValue(diff2, color);
|
|
194
|
-
}
|
|
195
|
-
return formatComplex(diff2, options, 0);
|
|
196
|
-
}
|
|
197
|
-
function formatValue(diff2, useColor) {
|
|
198
|
-
const prefix = getPrefix(diff2.type);
|
|
199
|
-
let value = "";
|
|
200
|
-
switch (diff2.type) {
|
|
201
|
-
case "added" /* ADDED */:
|
|
202
|
-
value = formatPrimitive(diff2.newValue);
|
|
203
|
-
return useColor ? `${colors.green}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
204
|
-
case "removed" /* REMOVED */:
|
|
205
|
-
value = formatPrimitive(diff2.oldValue);
|
|
206
|
-
return useColor ? `${colors.red}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
207
|
-
case "changed" /* CHANGED */:
|
|
208
|
-
const oldVal = formatPrimitive(diff2.oldValue);
|
|
209
|
-
const newVal = formatPrimitive(diff2.newValue);
|
|
210
|
-
let similarityInfo = "";
|
|
211
|
-
if (diff2.meta?.similarity !== void 0 && typeof diff2.oldValue === "string" && typeof diff2.newValue === "string") {
|
|
212
|
-
const similarity = Math.round(diff2.meta.similarity * 100);
|
|
213
|
-
similarityInfo = useColor ? `${colors.gray} (${similarity}% similar)${colors.reset}` : ` (${similarity}% similar)`;
|
|
214
|
-
}
|
|
215
|
-
const oldLine = useColor ? `${colors.red}- ${oldVal}${colors.reset}` : `- ${oldVal}`;
|
|
216
|
-
const newLine = useColor ? `${colors.green}+ ${newVal}${similarityInfo}${colors.reset}` : `+ ${newVal}${similarityInfo}`;
|
|
217
|
-
return `${oldLine}
|
|
218
|
-
${newLine}`;
|
|
219
|
-
default:
|
|
220
|
-
value = formatPrimitive(diff2.newValue ?? diff2.oldValue);
|
|
221
|
-
return useColor ? `${colors.gray}${prefix} ${value}${colors.reset}` : `${prefix} ${value}`;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
function formatComplex(diff2, options, indent = 0) {
|
|
225
|
-
const { full = false } = options;
|
|
226
|
-
if (diff2.type === "unchanged" /* UNCHANGED */ && !full && (!diff2.children || diff2.children.length === 0 || typeof diff2.oldValue !== "object" && typeof diff2.newValue !== "object")) {
|
|
227
|
-
return "";
|
|
228
|
-
}
|
|
229
|
-
return Array.isArray(diff2.oldValue) || Array.isArray(diff2.newValue) ? formatArrayDiff(diff2, options, indent) : formatObjectDiff(diff2, options, indent);
|
|
230
|
-
}
|
|
231
|
-
function formatArrayDiff(diff2, options, indent = 0) {
|
|
232
|
-
const { color = true, full = false } = options;
|
|
233
|
-
const baseIndent = " ".repeat(indent);
|
|
234
|
-
const innerIndent = " ".repeat(indent + 2);
|
|
235
|
-
let result = `[
|
|
236
|
-
`;
|
|
237
|
-
let visibleItems = 0;
|
|
238
|
-
if (diff2.children) {
|
|
239
|
-
for (let i = 0; i < diff2.children.length; i++) {
|
|
240
|
-
const child = diff2.children[i];
|
|
241
|
-
if (child.type === "unchanged" /* UNCHANGED */ && !full && (!child.children || child.children.length === 0)) {
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if (child.children && child.children.length > 0) {
|
|
245
|
-
const nestedOutput = Array.isArray(child.newValue || child.oldValue) ? formatArrayDiff(child, options, indent + 2) : formatObjectDiff(child, options, indent + 2);
|
|
246
|
-
if (nestedOutput.trim().length > 2) {
|
|
247
|
-
if (visibleItems > 0) {
|
|
248
|
-
result += ",\n";
|
|
249
|
-
}
|
|
250
|
-
result += innerIndent;
|
|
251
|
-
result += nestedOutput;
|
|
252
|
-
visibleItems++;
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
if (visibleItems > 0) {
|
|
256
|
-
result += ",\n";
|
|
257
|
-
}
|
|
258
|
-
switch (child.type) {
|
|
259
|
-
case "added" /* ADDED */:
|
|
260
|
-
result += color ? `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}+ ${formatPrimitive(child.newValue)}`;
|
|
261
|
-
visibleItems++;
|
|
262
|
-
break;
|
|
263
|
-
case "removed" /* REMOVED */:
|
|
264
|
-
result += color ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}` : `${innerIndent}- ${formatPrimitive(child.oldValue)}`;
|
|
265
|
-
visibleItems++;
|
|
266
|
-
break;
|
|
267
|
-
case "unchanged" /* UNCHANGED */:
|
|
268
|
-
if (child.meta?.ignored && child.path) {
|
|
269
|
-
result += color ? `${innerIndent}${colors.gray} ${child.path[child.path.length - 1] || ""}${colors.reset}` : `${innerIndent} ${child.path[child.path.length - 1] || ""}`;
|
|
270
|
-
} else {
|
|
271
|
-
result += color ? `${innerIndent}${colors.gray} ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent} ${formatPrimitive(child.newValue)}`;
|
|
272
|
-
}
|
|
273
|
-
visibleItems++;
|
|
274
|
-
break;
|
|
275
|
-
case "changed" /* CHANGED */:
|
|
276
|
-
result += color ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}
|
|
277
|
-
${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}- ${formatPrimitive(child.oldValue)}
|
|
278
|
-
${innerIndent}+ ${formatPrimitive(child.newValue)}`;
|
|
279
|
-
visibleItems++;
|
|
280
|
-
break;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
if (visibleItems > 0) {
|
|
286
|
-
result += "\n";
|
|
287
|
-
}
|
|
288
|
-
result += `${baseIndent}]`;
|
|
289
|
-
return result;
|
|
290
|
-
}
|
|
291
|
-
function formatObjectDiff(diff2, options, indent = 0) {
|
|
292
|
-
const { color = true, full = false } = options;
|
|
293
|
-
const baseIndent = " ".repeat(indent);
|
|
294
|
-
const innerIndent = " ".repeat(indent + 2);
|
|
295
|
-
let result = `{
|
|
296
|
-
`;
|
|
297
|
-
let visibleItems = 0;
|
|
298
|
-
if (diff2.children) {
|
|
299
|
-
const displayableChildren = diff2.children.filter((child) => {
|
|
300
|
-
if (child.type !== "unchanged" /* UNCHANGED */) return true;
|
|
301
|
-
if (full) return true;
|
|
302
|
-
if (child.children && child.children.length > 0) return true;
|
|
303
|
-
const key = child.path?.[child.path.length - 1] || "";
|
|
304
|
-
if (options.outputKeys?.includes(key)) return true;
|
|
305
|
-
return false;
|
|
306
|
-
});
|
|
307
|
-
for (let i = 0; i < displayableChildren.length; i++) {
|
|
308
|
-
const child = displayableChildren[i];
|
|
309
|
-
const key = child.path?.[child.path.length - 1] || "";
|
|
310
|
-
const isLast = i === displayableChildren.length - 1;
|
|
311
|
-
if (visibleItems > 0 && !result.endsWith("\n")) {
|
|
312
|
-
result += ",\n";
|
|
313
|
-
}
|
|
314
|
-
if (child.children && child.children.length > 0) {
|
|
315
|
-
const nestedContent = Array.isArray(child.newValue || child.oldValue) ? formatArrayDiff(child, options, indent + 2) : formatObjectDiff(child, options, indent + 2);
|
|
316
|
-
if (nestedContent.trim().length > 2) {
|
|
317
|
-
result += `${innerIndent}${key}: ${nestedContent}`;
|
|
318
|
-
visibleItems++;
|
|
319
|
-
}
|
|
320
|
-
} else {
|
|
321
|
-
switch (child.type) {
|
|
322
|
-
case "added" /* ADDED */:
|
|
323
|
-
result += color ? `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;
|
|
324
|
-
visibleItems++;
|
|
325
|
-
break;
|
|
326
|
-
case "removed" /* REMOVED */:
|
|
327
|
-
result += color ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}` : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}`;
|
|
328
|
-
visibleItems++;
|
|
329
|
-
break;
|
|
330
|
-
case "changed" /* CHANGED */:
|
|
331
|
-
result += color ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}
|
|
332
|
-
${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}
|
|
333
|
-
${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;
|
|
334
|
-
visibleItems++;
|
|
335
|
-
break;
|
|
336
|
-
case "unchanged" /* UNCHANGED */:
|
|
337
|
-
if (full || options.outputKeys?.includes(key)) {
|
|
338
|
-
if (child.meta?.ignored) {
|
|
339
|
-
result += color ? `${innerIndent}${colors.gray} ${key}${colors.reset}` : `${innerIndent} ${key}`;
|
|
340
|
-
} else {
|
|
341
|
-
result += color ? `${innerIndent}${colors.gray} ${key}: ${formatPrimitive(child.newValue)}${colors.reset}` : `${innerIndent} ${key}: ${formatPrimitive(child.newValue)}`;
|
|
342
|
-
}
|
|
343
|
-
visibleItems++;
|
|
344
|
-
}
|
|
345
|
-
break;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (!isLast && !result.endsWith("\n")) {
|
|
349
|
-
result += ",";
|
|
350
|
-
}
|
|
351
|
-
if (!result.endsWith("\n")) {
|
|
352
|
-
result += "\n";
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
if (visibleItems > 0 && !result.endsWith("\n")) {
|
|
357
|
-
result += "\n";
|
|
358
|
-
}
|
|
359
|
-
result += `${baseIndent}}`;
|
|
360
|
-
return result;
|
|
361
|
-
}
|
|
362
|
-
function getPrefix(type) {
|
|
363
|
-
switch (type) {
|
|
364
|
-
case "added" /* ADDED */:
|
|
365
|
-
return "+";
|
|
366
|
-
case "removed" /* REMOVED */:
|
|
367
|
-
return "-";
|
|
368
|
-
case "changed" /* CHANGED */:
|
|
369
|
-
return "!";
|
|
370
|
-
default:
|
|
371
|
-
return " ";
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
function formatPrimitive(value) {
|
|
375
|
-
if (value === void 0) {
|
|
376
|
-
return "undefined";
|
|
377
|
-
}
|
|
378
|
-
if (value === null) {
|
|
379
|
-
return "null";
|
|
380
|
-
}
|
|
381
|
-
if (typeof value === "string") {
|
|
382
|
-
return `'${value}'`;
|
|
383
|
-
}
|
|
384
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
385
|
-
return value.toString();
|
|
386
|
-
}
|
|
387
|
-
if (typeof value === "object") {
|
|
388
|
-
const json = JSON.stringify(value, null, 2);
|
|
389
|
-
return json;
|
|
390
|
-
}
|
|
391
|
-
return String(value);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// src/index.ts
|
|
395
|
-
function diffRaw(oldValue, newValue, options = {}) {
|
|
396
|
-
return createDiff(oldValue, newValue, options);
|
|
397
|
-
}
|
|
398
|
-
function diff(oldValue, newValue, options = {}) {
|
|
399
|
-
const diffResult = diffRaw(oldValue, newValue, options);
|
|
400
|
-
return formatDiff(diffResult, options);
|
|
401
|
-
}
|
|
402
|
-
export {
|
|
403
|
-
DiffType,
|
|
404
|
-
diff,
|
|
405
|
-
diffRaw
|
|
406
|
-
};
|
|
407
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import E from"leven";var h=($=>($.ADDED="added",$.REMOVED="removed",$.CHANGED="changed",$.UNCHANGED="unchanged",$))(h||{});function y(e,t,a={},r=[]){let{keysOnly:$=!1,ignoreValues:g=!1}=a;if(e===void 0&&t===void 0)return{type:"unchanged"};if(e===void 0)return{type:"added",path:r,newValue:t};if(t===void 0)return{type:"removed",path:r,oldValue:e};if(typeof e!="object"||typeof t!="object"||e===null||t===null){if($||g)return{type:"unchanged",path:r,oldValue:e,newValue:t,meta:{ignored:!0}};if(e===t)return{type:"unchanged",path:r,oldValue:e,newValue:t};if(typeof e=="string"&&typeof t=="string"){let n=E(e,t),s=Math.max(e.length,t.length),i=s>0?1-n/s:1;return{type:"changed",path:r,oldValue:e,newValue:t,meta:{levenDistance:n,similarity:i}}}return{type:"changed",path:r,oldValue:e,newValue:t}}return Array.isArray(e)&&Array.isArray(t)?R(e,t,a,r):N(e,t,a,r)}function N(e,t,a,r){let{ignoreKeys:$=[]}=a,g=new Set([...Object.keys(e).filter(i=>!$.includes(i)),...Object.keys(t).filter(i=>!$.includes(i))]),n=[],s=!1;for(let i of g){let c=[...r,i],l=e[i],f=t[i],D=y(l,f,a,c);D.type!=="unchanged"&&(s=!0),n.push(D)}return s?{type:"changed",path:r,oldValue:e,newValue:t,children:n}:{type:"unchanged",path:r,oldValue:e,newValue:t}}function R(e,t,a,r){if(e.length!==t.length){let n=[],s=Math.max(e.length,t.length);for(let i=0;i<s;i++){let c=[...r,i.toString()];i>=e.length?n.push({type:"added",path:c,newValue:t[i]}):i>=t.length?n.push({type:"removed",path:c,oldValue:e[i]}):n.push(y(e[i],t[i],a,c))}return{type:"changed",path:r,oldValue:e,newValue:t,children:n}}let $=[],g=!1;for(let n=0;n<e.length;n++){let s=[...r,n.toString()],i=e[n],c=t[n],l;if(typeof i=="string"&&typeof c=="string")if(i===c)l={type:"unchanged",path:s,oldValue:i,newValue:c};else{let f=E(i,c),D=Math.max(i.length,c.length),p=D>0?1-f/D:1;l={type:"changed",path:s,oldValue:i,newValue:c,meta:{levenDistance:f,similarity:p}},g=!0}else l=y(i,c,a,s),l.type!=="unchanged"&&(g=!0);$.push(l)}return g?{type:"changed",path:r,oldValue:e,newValue:t,children:$}:{type:"unchanged",path:r,oldValue:e,newValue:t}}var u={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",gray:"\x1B[90m"};function b(e,t={}){let{color:a=!0,full:r=!1}=t;return e.type==="unchanged"&&!r&&(!e.children||e.children.length===0)?"":!e.children||e.children.length===0?A(e,a):C(e,t,0)}function A(e,t){let a=G(e.type),r="";switch(e.type){case"added":return r=o(e.newValue),t?`${u.green}${a} ${r}${u.reset}`:`${a} ${r}`;case"removed":return r=o(e.oldValue),t?`${u.red}${a} ${r}${u.reset}`:`${a} ${r}`;case"changed":let $=o(e.oldValue),g=o(e.newValue),n="";if(e.meta?.similarity!==void 0&&typeof e.oldValue=="string"&&typeof e.newValue=="string"){let c=Math.round(e.meta.similarity*100);n=t?`${u.gray} (${c}% similar)${u.reset}`:` (${c}% similar)`}let s=t?`${u.red}- ${$}${u.reset}`:`- ${$}`,i=t?`${u.green}+ ${g}${n}${u.reset}`:`+ ${g}${n}`;return`${s}
|
|
2
|
+
${i}`;default:return r=o(e.newValue??e.oldValue),t?`${u.gray}${a} ${r}${u.reset}`:`${a} ${r}`}}function C(e,t,a=0){let{full:r=!1}=t;return e.type==="unchanged"&&!r&&(!e.children||e.children.length===0||typeof e.oldValue!="object"&&typeof e.newValue!="object")?"":Array.isArray(e.oldValue)||Array.isArray(e.newValue)?m(e,t,a):d(e,t,a)}function m(e,t,a=0){let{color:r=!0,full:$=!1}=t,g=" ".repeat(a),n=" ".repeat(a+2),s=`[
|
|
3
|
+
`,i=0;if(e.children)for(let c=0;c<e.children.length;c++){let l=e.children[c];if(!(l.type==="unchanged"&&!$&&(!l.children||l.children.length===0)))if(l.children&&l.children.length>0){let f=Array.isArray(l.newValue||l.oldValue)?m(l,t,a+2):d(l,t,a+2);f.trim().length>2&&(i>0&&(s+=`,
|
|
4
|
+
`),s+=n,s+=f,i++)}else switch(i>0&&(s+=`,
|
|
5
|
+
`),l.type){case"added":s+=r?`${n}${u.green}+ ${o(l.newValue)}${u.reset}`:`${n}+ ${o(l.newValue)}`,i++;break;case"removed":s+=r?`${n}${u.red}- ${o(l.oldValue)}${u.reset}`:`${n}- ${o(l.oldValue)}`,i++;break;case"unchanged":l.meta?.ignored&&l.path?s+=r?`${n}${u.gray} ${l.path[l.path.length-1]||""}${u.reset}`:`${n} ${l.path[l.path.length-1]||""}`:s+=r?`${n}${u.gray} ${o(l.newValue)}${u.reset}`:`${n} ${o(l.newValue)}`,i++;break;case"changed":s+=r?`${n}${u.red}- ${o(l.oldValue)}${u.reset}
|
|
6
|
+
${n}${u.green}+ ${o(l.newValue)}${u.reset}`:`${n}- ${o(l.oldValue)}
|
|
7
|
+
${n}+ ${o(l.newValue)}`,i++;break}}return i>0&&(s+=`
|
|
8
|
+
`),s+=`${g}]`,s}function d(e,t,a=0){let{color:r=!0,full:$=!1}=t,g=" ".repeat(a),n=" ".repeat(a+2),s=`{
|
|
9
|
+
`,i=0;if(e.children){let c=e.children.filter(l=>{if(l.type!=="unchanged"||$||l.children&&l.children.length>0)return!0;let f=l.path?.[l.path.length-1]||"";return!!t.outputKeys?.includes(f)});for(let l=0;l<c.length;l++){let f=c[l],D=f.path?.[f.path.length-1]||"",p=l===c.length-1;if(i>0&&!s.endsWith(`
|
|
10
|
+
`)&&(s+=`,
|
|
11
|
+
`),f.children&&f.children.length>0){let V=Array.isArray(f.newValue||f.oldValue)?m(f,t,a+2):d(f,t,a+2);V.trim().length>2&&(s+=`${n}${D}: ${V}`,i++)}else switch(f.type){case"added":s+=r?`${n}${u.green}+ ${D}: ${o(f.newValue)}${u.reset}`:`${n}+ ${D}: ${o(f.newValue)}`,i++;break;case"removed":s+=r?`${n}${u.red}- ${D}: ${o(f.oldValue)}${u.reset}`:`${n}- ${D}: ${o(f.oldValue)}`,i++;break;case"changed":s+=r?`${n}${u.red}- ${D}: ${o(f.oldValue)}${u.reset}
|
|
12
|
+
${n}${u.green}+ ${D}: ${o(f.newValue)}${u.reset}`:`${n}- ${D}: ${o(f.oldValue)}
|
|
13
|
+
${n}+ ${D}: ${o(f.newValue)}`,i++;break;case"unchanged":($||t.outputKeys?.includes(D))&&(f.meta?.ignored?s+=r?`${n}${u.gray} ${D}${u.reset}`:`${n} ${D}`:s+=r?`${n}${u.gray} ${D}: ${o(f.newValue)}${u.reset}`:`${n} ${D}: ${o(f.newValue)}`,i++);break}!p&&!s.endsWith(`
|
|
14
|
+
`)&&(s+=","),s.endsWith(`
|
|
15
|
+
`)||(s+=`
|
|
16
|
+
`)}}return i>0&&!s.endsWith(`
|
|
17
|
+
`)&&(s+=`
|
|
18
|
+
`),s+=`${g}}`,s}function G(e){switch(e){case"added":return"+";case"removed":return"-";case"changed":return"!";default:return" "}}function o(e){return e===void 0?"undefined":e===null?"null":typeof e=="string"?`'${e}'`:typeof e=="number"||typeof e=="boolean"?e.toString():typeof e=="object"?JSON.stringify(e,null,2):String(e)}function H(e,t,a={}){return y(e,t,a)}function v(e,t,a={}){let r=H(e,t,a);return b(r,a)}export{h as DiffType,v as diff,H as diffRaw};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diff-leven",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Git like diff between two strings, using the Levenshtein distance algorithm",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -27,7 +27,11 @@
|
|
|
27
27
|
"url": "git+https://github.com/kushalshit27/diff-leven.git"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
|
-
"diff"
|
|
30
|
+
"diff",
|
|
31
|
+
"leven",
|
|
32
|
+
"compare",
|
|
33
|
+
"levenshtein",
|
|
34
|
+
"comparison"
|
|
31
35
|
],
|
|
32
36
|
"author": "kushalshit27",
|
|
33
37
|
"license": "MIT",
|
|
@@ -50,8 +54,5 @@
|
|
|
50
54
|
},
|
|
51
55
|
"dependencies": {
|
|
52
56
|
"leven": "^4.0.0"
|
|
53
|
-
},
|
|
54
|
-
"publishConfig": {
|
|
55
|
-
"access": "public"
|
|
56
57
|
}
|
|
57
58
|
}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/diff.ts","../src/types.ts","../src/formatter.ts"],"sourcesContent":["import { createDiff } from './diff';\nimport { formatDiff } from './formatter';\nimport { DiffOptions, DiffResult, DiffType, SerializableValue } from './types';\n\n/**\n * Compare two values and generate a detailed diff result object\n *\n * @param oldValue - Original value to compare from\n * @param newValue - New value to compare against\n * @param options - Configuration options for the diff\n * @returns A structured diff result object\n */\nexport function diffRaw(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n): DiffResult {\n return createDiff(oldValue, newValue, options);\n}\n\n/**\n * Compare two values and generate a formatted diff string\n *\n * @param oldValue - Original value to compare from\n * @param newValue - New value to compare against\n * @param options - Configuration options for the diff\n * @returns A formatted string representation of the diff\n */\nexport function diff(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n): string {\n const diffResult = diffRaw(oldValue, newValue, options);\n return formatDiff(diffResult, options);\n}\n\n// Export types\nexport type { DiffOptions, DiffResult, SerializableValue };\nexport { DiffType };\n","import leven from 'leven';\nimport { DiffOptions, DiffResult, DiffType, SerializableValue } from './types';\n\n/**\n * Compares two values (objects, arrays, strings, etc.) and creates a diff result\n * Uses the Levenshtein distance algorithm for string comparison\n *\n * @param oldValue - The original value to compare\n * @param newValue - The new value to compare against\n * @param options - Configuration options\n * @param path - Current path in the object tree (used internally for recursion)\n * @returns A diff result object\n */\nexport function createDiff(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n path: string[] = [],\n): DiffResult {\n const { keysOnly = false, ignoreValues = false } = options;\n\n // Handle case where one or both values are undefined\n if (oldValue === undefined && newValue === undefined) {\n return { type: DiffType.UNCHANGED };\n }\n if (oldValue === undefined) {\n return { type: DiffType.ADDED, path, newValue };\n }\n if (newValue === undefined) {\n return { type: DiffType.REMOVED, path, oldValue };\n }\n\n // Handle primitive values\n if (\n typeof oldValue !== 'object' ||\n typeof newValue !== 'object' ||\n oldValue === null ||\n newValue === null\n ) {\n if (keysOnly || ignoreValues) {\n // For ignoreValues, retain the path information for better formatting\n return {\n type: DiffType.UNCHANGED,\n path,\n oldValue,\n newValue,\n meta: { ignored: true },\n };\n }\n if (oldValue === newValue) {\n return { type: DiffType.UNCHANGED, path, oldValue, newValue };\n }\n\n // Special handling for strings - use Levenshtein distance\n if (typeof oldValue === 'string' && typeof newValue === 'string') {\n const distance = leven(oldValue, newValue);\n const maxLength = Math.max(oldValue.length, newValue.length);\n const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;\n\n return {\n type: DiffType.CHANGED,\n path,\n oldValue,\n newValue,\n meta: {\n levenDistance: distance,\n similarity: similarityRatio,\n },\n };\n }\n\n return { type: DiffType.CHANGED, path, oldValue, newValue };\n }\n\n // Handle arrays\n if (Array.isArray(oldValue) && Array.isArray(newValue)) {\n return compareArrays(oldValue, newValue, options, path);\n }\n\n // Handle objects\n return compareObjects(\n oldValue as Record<string, any>,\n newValue as Record<string, any>,\n options,\n path,\n );\n}\n\n/**\n * Compare two objects and generate a diff\n */\nfunction compareObjects(\n oldObj: Record<string, any>,\n newObj: Record<string, any>,\n options: DiffOptions,\n path: string[],\n): DiffResult {\n const { ignoreKeys = [] } = options;\n\n const allKeys = new Set([\n ...Object.keys(oldObj).filter((key) => !ignoreKeys.includes(key)),\n ...Object.keys(newObj).filter((key) => !ignoreKeys.includes(key)),\n ]);\n\n const children: DiffResult[] = [];\n let hasChanges = false;\n\n for (const key of allKeys) {\n const childPath = [...path, key];\n const oldValue = oldObj[key];\n const newValue = newObj[key];\n\n const childDiff = createDiff(oldValue, newValue, options, childPath);\n\n if (childDiff.type !== DiffType.UNCHANGED) {\n hasChanges = true;\n }\n\n children.push(childDiff);\n }\n\n if (hasChanges) {\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldObj,\n newValue: newObj,\n children,\n };\n }\n\n return { type: DiffType.UNCHANGED, path, oldValue: oldObj, newValue: newObj };\n}\n\n/**\n * Compare two arrays and generate a diff\n * Uses Levenshtein distance for finding optimal matching between array elements\n */\nfunction compareArrays(\n oldArray: any[],\n newArray: any[],\n options: DiffOptions,\n path: string[],\n): DiffResult {\n // Simple case: arrays of different lengths\n if (oldArray.length !== newArray.length) {\n const children: DiffResult[] = [];\n const maxLength = Math.max(oldArray.length, newArray.length);\n\n for (let i = 0; i < maxLength; i++) {\n const childPath = [...path, i.toString()];\n if (i >= oldArray.length) {\n children.push({\n type: DiffType.ADDED,\n path: childPath,\n newValue: newArray[i],\n });\n } else if (i >= newArray.length) {\n children.push({\n type: DiffType.REMOVED,\n path: childPath,\n oldValue: oldArray[i],\n });\n } else {\n children.push(createDiff(oldArray[i], newArray[i], options, childPath));\n }\n }\n\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n children,\n };\n }\n\n // For arrays of primitive values or objects, compare each element\n const children: DiffResult[] = [];\n let hasChanges = false;\n\n for (let i = 0; i < oldArray.length; i++) {\n const childPath = [...path, i.toString()];\n const oldValue = oldArray[i];\n const newValue = newArray[i];\n let childDiff;\n\n // Special handling for strings - use Levenshtein distance\n if (typeof oldValue === 'string' && typeof newValue === 'string') {\n if (oldValue === newValue) {\n childDiff = {\n type: DiffType.UNCHANGED,\n path: childPath,\n oldValue,\n newValue,\n };\n } else {\n const distance = leven(oldValue, newValue);\n const maxLength = Math.max(oldValue.length, newValue.length);\n const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;\n\n childDiff = {\n type: DiffType.CHANGED,\n path: childPath,\n oldValue,\n newValue,\n meta: {\n levenDistance: distance,\n similarity: similarityRatio,\n },\n };\n hasChanges = true;\n }\n } else {\n // For other types\n childDiff = createDiff(oldValue, newValue, options, childPath);\n if (childDiff.type !== DiffType.UNCHANGED) {\n hasChanges = true;\n }\n }\n\n children.push(childDiff);\n }\n\n if (hasChanges) {\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n children,\n };\n }\n\n return {\n type: DiffType.UNCHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n };\n}\n","/**\n * Options for diff generation\n */\nexport interface DiffOptions {\n /**\n * Whether to use colorized output\n * @default true\n */\n color?: boolean;\n\n /**\n * Only compare object keys/structure (ignore values)\n * @default false\n */\n keysOnly?: boolean;\n\n /**\n * Output the entire object tree, not just differences\n * @default false\n */\n full?: boolean;\n\n /**\n * Always include these keys in output for objects with differences\n * @default []\n */\n outputKeys?: string[];\n\n /**\n * Skip these keys when comparing objects\n * @default []\n */\n ignoreKeys?: string[];\n\n /**\n * Ignore value differences, focus only on structure\n * @default false\n */\n ignoreValues?: boolean;\n}\n\n/**\n * Enum for diff change types\n */\nexport enum DiffType {\n ADDED = 'added',\n REMOVED = 'removed',\n CHANGED = 'changed',\n UNCHANGED = 'unchanged',\n}\n\n/**\n * Represents a change between two values\n */\nexport interface DiffResult {\n type: DiffType;\n path?: string[];\n oldValue?: any;\n newValue?: any;\n children?: DiffResult[];\n /**\n * Additional metadata about the diff, such as Levenshtein distance metrics\n */\n meta?: {\n /** Levenshtein distance between strings */\n levenDistance?: number;\n /** Similarity ratio (0-1) where 1 means identical */\n similarity?: number;\n /** Any other metadata properties */\n [key: string]: any;\n };\n}\n\n/**\n * Type for handling any serializable value\n */\nexport type SerializableValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | { [key: string]: SerializableValue }\n | SerializableValue[];\n","import { DiffOptions, DiffResult, DiffType } from './types';\n\n// ANSI color codes\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n gray: '\\x1b[90m',\n};\n\n/**\n * Format a diff result as a string with optional colors and formatting\n * @param diff - The diff result to format\n * @param options - Formatting options\n * @returns A formatted string representation of the diff\n */\nexport function formatDiff(\n diff: DiffResult,\n options: DiffOptions = {},\n): string {\n const { color = true, full = false } = options;\n\n // For unchanged values with no children, we may skip them unless full output is requested\n if (\n diff.type === DiffType.UNCHANGED &&\n !full &&\n (!diff.children || diff.children.length === 0)\n ) {\n return '';\n }\n\n // Handle primitive values\n if (!diff.children || diff.children.length === 0) {\n return formatValue(diff, color);\n }\n\n // Handle objects and arrays\n return formatComplex(diff, options, 0);\n}\n\n/**\n * Format a primitive value diff (added, removed, changed)\n */\nfunction formatValue(diff: DiffResult, useColor: boolean): string {\n const prefix = getPrefix(diff.type);\n let value = '';\n\n switch (diff.type) {\n case DiffType.ADDED:\n value = formatPrimitive(diff.newValue);\n return useColor\n ? `${colors.green}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n\n case DiffType.REMOVED:\n value = formatPrimitive(diff.oldValue);\n return useColor\n ? `${colors.red}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n\n case DiffType.CHANGED:\n const oldVal = formatPrimitive(diff.oldValue);\n const newVal = formatPrimitive(diff.newValue);\n\n // Add similarity information for strings if available\n let similarityInfo = '';\n if (\n diff.meta?.similarity !== undefined &&\n typeof diff.oldValue === 'string' &&\n typeof diff.newValue === 'string'\n ) {\n const similarity = Math.round(diff.meta.similarity * 100);\n similarityInfo = useColor\n ? `${colors.gray} (${similarity}% similar)${colors.reset}`\n : ` (${similarity}% similar)`;\n }\n\n // Git-style diff format: -old value followed by +new value\n const oldLine = useColor\n ? `${colors.red}- ${oldVal}${colors.reset}`\n : `- ${oldVal}`;\n\n const newLine = useColor\n ? `${colors.green}+ ${newVal}${similarityInfo}${colors.reset}`\n : `+ ${newVal}${similarityInfo}`;\n\n return `${oldLine}\\n${newLine}`;\n\n default:\n value = formatPrimitive(diff.newValue ?? diff.oldValue);\n return useColor\n ? `${colors.gray}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n }\n}\n\n/**\n * Format complex objects and arrays\n * For objects, use Git-like diff format with JSON-style indentation\n */\nfunction formatComplex(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { full = false } = options;\n\n // Early return for unchanged primitives\n if (\n diff.type === DiffType.UNCHANGED &&\n !full &&\n (!diff.children ||\n diff.children.length === 0 ||\n (typeof diff.oldValue !== 'object' && typeof diff.newValue !== 'object'))\n ) {\n return '';\n }\n\n return Array.isArray(diff.oldValue) || Array.isArray(diff.newValue)\n ? formatArrayDiff(diff, options, indent)\n : formatObjectDiff(diff, options, indent);\n}\n\n/**\n * Format array diffs with proper indentation and Git-style markers\n */\nfunction formatArrayDiff(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { color = true, full = false } = options;\n const baseIndent = ' '.repeat(indent);\n const innerIndent = ' '.repeat(indent + 2);\n let result = `[\\n`;\n let visibleItems = 0;\n\n if (diff.children) {\n for (let i = 0; i < diff.children.length; i++) {\n const child = diff.children[i];\n\n // Skip unchanged items unless full output is requested\n if (\n child.type === DiffType.UNCHANGED &&\n !full &&\n (!child.children || child.children.length === 0)\n ) {\n continue;\n }\n\n if (child.children && child.children.length > 0) {\n // Handle nested objects/arrays within the array\n const nestedOutput = Array.isArray(child.newValue || child.oldValue)\n ? formatArrayDiff(child, options, indent + 2)\n : formatObjectDiff(child, options, indent + 2);\n\n // Only add if there's actual content\n if (nestedOutput.trim().length > 2) {\n // More than just '[]' or '{}'\n if (visibleItems > 0) {\n result += ',\\n';\n }\n result += innerIndent;\n result += nestedOutput;\n visibleItems++;\n }\n } else {\n // Handle primitive values\n if (visibleItems > 0) {\n result += ',\\n';\n }\n\n switch (child.type) {\n case DiffType.ADDED:\n result += color\n ? `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}+ ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.REMOVED:\n result += color\n ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}`\n : `${innerIndent}- ${formatPrimitive(child.oldValue)}`;\n visibleItems++;\n break;\n case DiffType.UNCHANGED:\n // Special handling for ignored values (when using ignoreValues: true)\n if (child.meta?.ignored && child.path) {\n result += color\n ? `${innerIndent}${colors.gray} ${child.path[child.path.length - 1] || ''}${colors.reset}`\n : `${innerIndent} ${child.path[child.path.length - 1] || ''}`;\n } else {\n result += color\n ? `${innerIndent}${colors.gray} ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent} ${formatPrimitive(child.newValue)}`;\n }\n visibleItems++;\n break;\n case DiffType.CHANGED:\n result += color\n ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}\\n` +\n `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}- ${formatPrimitive(child.oldValue)}\\n` +\n `${innerIndent}+ ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n }\n }\n }\n }\n\n if (visibleItems > 0) {\n result += '\\n';\n }\n result += `${baseIndent}]`;\n return result;\n}\n\n/**\n * Format object diffs with proper indentation and Git-style markers\n */\nfunction formatObjectDiff(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { color = true, full = false } = options;\n const baseIndent = ' '.repeat(indent);\n const innerIndent = ' '.repeat(indent + 2);\n let result = `{\\n`;\n let visibleItems = 0;\n\n if (diff.children) {\n // First, filter out children that won't be displayed\n const displayableChildren = diff.children.filter((child) => {\n if (child.type !== DiffType.UNCHANGED) return true;\n if (full) return true;\n if (child.children && child.children.length > 0) return true;\n const key = child.path?.[child.path.length - 1] || '';\n if (options.outputKeys?.includes(key)) return true;\n return false;\n });\n\n for (let i = 0; i < displayableChildren.length; i++) {\n const child = displayableChildren[i];\n const key = child.path?.[child.path.length - 1] || '';\n const isLast = i === displayableChildren.length - 1;\n\n // If we already added an item, and we're not at a new line, add a comma and new line\n if (visibleItems > 0 && !result.endsWith('\\n')) {\n result += ',\\n';\n }\n\n if (child.children && child.children.length > 0) {\n // Handle nested objects/arrays\n const nestedContent = Array.isArray(child.newValue || child.oldValue)\n ? formatArrayDiff(child, options, indent + 2)\n : formatObjectDiff(child, options, indent + 2);\n\n // Only add if there's actual content in the nested structure\n if (nestedContent.trim().length > 2) {\n // More than just '{}' or '[]'\n result += `${innerIndent}${key}: ${nestedContent}`;\n visibleItems++;\n }\n } else {\n // Handle primitive values\n switch (child.type) {\n case DiffType.ADDED:\n result += color\n ? `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.REMOVED:\n result += color\n ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}`\n : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}`;\n visibleItems++;\n break;\n case DiffType.CHANGED:\n result += color\n ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}\\n` +\n `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}\\n` +\n `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.UNCHANGED:\n if (full || options.outputKeys?.includes(key)) {\n // Special handling for ignored values (when using ignoreValues: true)\n if (child.meta?.ignored) {\n result += color\n ? `${innerIndent}${colors.gray} ${key}${colors.reset}`\n : `${innerIndent} ${key}`;\n } else {\n result += color\n ? `${innerIndent}${colors.gray} ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent} ${key}: ${formatPrimitive(child.newValue)}`;\n }\n visibleItems++;\n }\n break;\n }\n }\n\n // Add comma if not the last item and not already ending with newline\n if (!isLast && !result.endsWith('\\n')) {\n result += ',';\n }\n\n // Always ensure we end with a newline before the next item\n if (!result.endsWith('\\n')) {\n result += '\\n';\n }\n }\n }\n\n // Only add final newline if we have content\n if (visibleItems > 0 && !result.endsWith('\\n')) {\n result += '\\n';\n }\n\n result += `${baseIndent}}`;\n return result;\n}\n\n/**\n * Get the prefix for a diff type\n */\nfunction getPrefix(type: DiffType | string): string {\n switch (type) {\n case DiffType.ADDED:\n return '+';\n case DiffType.REMOVED:\n return '-';\n case DiffType.CHANGED:\n return '!';\n default:\n return ' ';\n }\n}\n\n/**\n * Format a primitive value for output\n */\nfunction formatPrimitive(value: any): string {\n if (value === undefined) {\n return 'undefined';\n }\n\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'string') {\n // Use JavaScript object notation with single quotes\n return `'${value}'`;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n\n // For objects and arrays, use properly formatted JavaScript object notation\n if (typeof value === 'object') {\n const json = JSON.stringify(value, null, 2);\n return json;\n }\n\n return String(value);\n}\n"],"mappings":"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","names":["DiffType","leven","children","diff"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/diff.ts","../src/types.ts","../src/formatter.ts","../src/index.ts"],"sourcesContent":["import leven from 'leven';\nimport { DiffOptions, DiffResult, DiffType, SerializableValue } from './types';\n\n/**\n * Compares two values (objects, arrays, strings, etc.) and creates a diff result\n * Uses the Levenshtein distance algorithm for string comparison\n *\n * @param oldValue - The original value to compare\n * @param newValue - The new value to compare against\n * @param options - Configuration options\n * @param path - Current path in the object tree (used internally for recursion)\n * @returns A diff result object\n */\nexport function createDiff(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n path: string[] = [],\n): DiffResult {\n const { keysOnly = false, ignoreValues = false } = options;\n\n // Handle case where one or both values are undefined\n if (oldValue === undefined && newValue === undefined) {\n return { type: DiffType.UNCHANGED };\n }\n if (oldValue === undefined) {\n return { type: DiffType.ADDED, path, newValue };\n }\n if (newValue === undefined) {\n return { type: DiffType.REMOVED, path, oldValue };\n }\n\n // Handle primitive values\n if (\n typeof oldValue !== 'object' ||\n typeof newValue !== 'object' ||\n oldValue === null ||\n newValue === null\n ) {\n if (keysOnly || ignoreValues) {\n // For ignoreValues, retain the path information for better formatting\n return {\n type: DiffType.UNCHANGED,\n path,\n oldValue,\n newValue,\n meta: { ignored: true },\n };\n }\n if (oldValue === newValue) {\n return { type: DiffType.UNCHANGED, path, oldValue, newValue };\n }\n\n // Special handling for strings - use Levenshtein distance\n if (typeof oldValue === 'string' && typeof newValue === 'string') {\n const distance = leven(oldValue, newValue);\n const maxLength = Math.max(oldValue.length, newValue.length);\n const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;\n\n return {\n type: DiffType.CHANGED,\n path,\n oldValue,\n newValue,\n meta: {\n levenDistance: distance,\n similarity: similarityRatio,\n },\n };\n }\n\n return { type: DiffType.CHANGED, path, oldValue, newValue };\n }\n\n // Handle arrays\n if (Array.isArray(oldValue) && Array.isArray(newValue)) {\n return compareArrays(oldValue, newValue, options, path);\n }\n\n // Handle objects\n return compareObjects(\n oldValue as Record<string, any>,\n newValue as Record<string, any>,\n options,\n path,\n );\n}\n\n/**\n * Compare two objects and generate a diff\n */\nfunction compareObjects(\n oldObj: Record<string, any>,\n newObj: Record<string, any>,\n options: DiffOptions,\n path: string[],\n): DiffResult {\n const { ignoreKeys = [] } = options;\n\n const allKeys = new Set([\n ...Object.keys(oldObj).filter((key) => !ignoreKeys.includes(key)),\n ...Object.keys(newObj).filter((key) => !ignoreKeys.includes(key)),\n ]);\n\n const children: DiffResult[] = [];\n let hasChanges = false;\n\n for (const key of allKeys) {\n const childPath = [...path, key];\n const oldValue = oldObj[key];\n const newValue = newObj[key];\n\n const childDiff = createDiff(oldValue, newValue, options, childPath);\n\n if (childDiff.type !== DiffType.UNCHANGED) {\n hasChanges = true;\n }\n\n children.push(childDiff);\n }\n\n if (hasChanges) {\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldObj,\n newValue: newObj,\n children,\n };\n }\n\n return { type: DiffType.UNCHANGED, path, oldValue: oldObj, newValue: newObj };\n}\n\n/**\n * Compare two arrays and generate a diff\n * Uses Levenshtein distance for finding optimal matching between array elements\n */\nfunction compareArrays(\n oldArray: any[],\n newArray: any[],\n options: DiffOptions,\n path: string[],\n): DiffResult {\n // Simple case: arrays of different lengths\n if (oldArray.length !== newArray.length) {\n const children: DiffResult[] = [];\n const maxLength = Math.max(oldArray.length, newArray.length);\n\n for (let i = 0; i < maxLength; i++) {\n const childPath = [...path, i.toString()];\n if (i >= oldArray.length) {\n children.push({\n type: DiffType.ADDED,\n path: childPath,\n newValue: newArray[i],\n });\n } else if (i >= newArray.length) {\n children.push({\n type: DiffType.REMOVED,\n path: childPath,\n oldValue: oldArray[i],\n });\n } else {\n children.push(createDiff(oldArray[i], newArray[i], options, childPath));\n }\n }\n\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n children,\n };\n }\n\n // For arrays of primitive values or objects, compare each element\n const children: DiffResult[] = [];\n let hasChanges = false;\n\n for (let i = 0; i < oldArray.length; i++) {\n const childPath = [...path, i.toString()];\n const oldValue = oldArray[i];\n const newValue = newArray[i];\n let childDiff;\n\n // Special handling for strings - use Levenshtein distance\n if (typeof oldValue === 'string' && typeof newValue === 'string') {\n if (oldValue === newValue) {\n childDiff = {\n type: DiffType.UNCHANGED,\n path: childPath,\n oldValue,\n newValue,\n };\n } else {\n const distance = leven(oldValue, newValue);\n const maxLength = Math.max(oldValue.length, newValue.length);\n const similarityRatio = maxLength > 0 ? 1 - distance / maxLength : 1;\n\n childDiff = {\n type: DiffType.CHANGED,\n path: childPath,\n oldValue,\n newValue,\n meta: {\n levenDistance: distance,\n similarity: similarityRatio,\n },\n };\n hasChanges = true;\n }\n } else {\n // For other types\n childDiff = createDiff(oldValue, newValue, options, childPath);\n if (childDiff.type !== DiffType.UNCHANGED) {\n hasChanges = true;\n }\n }\n\n children.push(childDiff);\n }\n\n if (hasChanges) {\n return {\n type: DiffType.CHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n children,\n };\n }\n\n return {\n type: DiffType.UNCHANGED,\n path,\n oldValue: oldArray,\n newValue: newArray,\n };\n}\n","/**\n * Options for diff generation\n */\nexport interface DiffOptions {\n /**\n * Whether to use colorized output\n * @default true\n */\n color?: boolean;\n\n /**\n * Only compare object keys/structure (ignore values)\n * @default false\n */\n keysOnly?: boolean;\n\n /**\n * Output the entire object tree, not just differences\n * @default false\n */\n full?: boolean;\n\n /**\n * Always include these keys in output for objects with differences\n * @default []\n */\n outputKeys?: string[];\n\n /**\n * Skip these keys when comparing objects\n * @default []\n */\n ignoreKeys?: string[];\n\n /**\n * Ignore value differences, focus only on structure\n * @default false\n */\n ignoreValues?: boolean;\n}\n\n/**\n * Enum for diff change types\n */\nexport enum DiffType {\n ADDED = 'added',\n REMOVED = 'removed',\n CHANGED = 'changed',\n UNCHANGED = 'unchanged',\n}\n\n/**\n * Represents a change between two values\n */\nexport interface DiffResult {\n type: DiffType;\n path?: string[];\n oldValue?: any;\n newValue?: any;\n children?: DiffResult[];\n /**\n * Additional metadata about the diff, such as Levenshtein distance metrics\n */\n meta?: {\n /** Levenshtein distance between strings */\n levenDistance?: number;\n /** Similarity ratio (0-1) where 1 means identical */\n similarity?: number;\n /** Any other metadata properties */\n [key: string]: any;\n };\n}\n\n/**\n * Type for handling any serializable value\n */\nexport type SerializableValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | { [key: string]: SerializableValue }\n | SerializableValue[];\n","import { DiffOptions, DiffResult, DiffType } from './types';\n\n// ANSI color codes\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n gray: '\\x1b[90m',\n};\n\n/**\n * Format a diff result as a string with optional colors and formatting\n * @param diff - The diff result to format\n * @param options - Formatting options\n * @returns A formatted string representation of the diff\n */\nexport function formatDiff(\n diff: DiffResult,\n options: DiffOptions = {},\n): string {\n const { color = true, full = false } = options;\n\n // For unchanged values with no children, we may skip them unless full output is requested\n if (\n diff.type === DiffType.UNCHANGED &&\n !full &&\n (!diff.children || diff.children.length === 0)\n ) {\n return '';\n }\n\n // Handle primitive values\n if (!diff.children || diff.children.length === 0) {\n return formatValue(diff, color);\n }\n\n // Handle objects and arrays\n return formatComplex(diff, options, 0);\n}\n\n/**\n * Format a primitive value diff (added, removed, changed)\n */\nfunction formatValue(diff: DiffResult, useColor: boolean): string {\n const prefix = getPrefix(diff.type);\n let value = '';\n\n switch (diff.type) {\n case DiffType.ADDED:\n value = formatPrimitive(diff.newValue);\n return useColor\n ? `${colors.green}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n\n case DiffType.REMOVED:\n value = formatPrimitive(diff.oldValue);\n return useColor\n ? `${colors.red}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n\n case DiffType.CHANGED:\n const oldVal = formatPrimitive(diff.oldValue);\n const newVal = formatPrimitive(diff.newValue);\n\n // Add similarity information for strings if available\n let similarityInfo = '';\n if (\n diff.meta?.similarity !== undefined &&\n typeof diff.oldValue === 'string' &&\n typeof diff.newValue === 'string'\n ) {\n const similarity = Math.round(diff.meta.similarity * 100);\n similarityInfo = useColor\n ? `${colors.gray} (${similarity}% similar)${colors.reset}`\n : ` (${similarity}% similar)`;\n }\n\n // Git-style diff format: -old value followed by +new value\n const oldLine = useColor\n ? `${colors.red}- ${oldVal}${colors.reset}`\n : `- ${oldVal}`;\n\n const newLine = useColor\n ? `${colors.green}+ ${newVal}${similarityInfo}${colors.reset}`\n : `+ ${newVal}${similarityInfo}`;\n\n return `${oldLine}\\n${newLine}`;\n\n default:\n value = formatPrimitive(diff.newValue ?? diff.oldValue);\n return useColor\n ? `${colors.gray}${prefix} ${value}${colors.reset}`\n : `${prefix} ${value}`;\n }\n}\n\n/**\n * Format complex objects and arrays\n * For objects, use Git-like diff format with JSON-style indentation\n */\nfunction formatComplex(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { full = false } = options;\n\n // Early return for unchanged primitives\n if (\n diff.type === DiffType.UNCHANGED &&\n !full &&\n (!diff.children ||\n diff.children.length === 0 ||\n (typeof diff.oldValue !== 'object' && typeof diff.newValue !== 'object'))\n ) {\n return '';\n }\n\n return Array.isArray(diff.oldValue) || Array.isArray(diff.newValue)\n ? formatArrayDiff(diff, options, indent)\n : formatObjectDiff(diff, options, indent);\n}\n\n/**\n * Format array diffs with proper indentation and Git-style markers\n */\nfunction formatArrayDiff(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { color = true, full = false } = options;\n const baseIndent = ' '.repeat(indent);\n const innerIndent = ' '.repeat(indent + 2);\n let result = `[\\n`;\n let visibleItems = 0;\n\n if (diff.children) {\n for (let i = 0; i < diff.children.length; i++) {\n const child = diff.children[i];\n\n // Skip unchanged items unless full output is requested\n if (\n child.type === DiffType.UNCHANGED &&\n !full &&\n (!child.children || child.children.length === 0)\n ) {\n continue;\n }\n\n if (child.children && child.children.length > 0) {\n // Handle nested objects/arrays within the array\n const nestedOutput = Array.isArray(child.newValue || child.oldValue)\n ? formatArrayDiff(child, options, indent + 2)\n : formatObjectDiff(child, options, indent + 2);\n\n // Only add if there's actual content\n if (nestedOutput.trim().length > 2) {\n // More than just '[]' or '{}'\n if (visibleItems > 0) {\n result += ',\\n';\n }\n result += innerIndent;\n result += nestedOutput;\n visibleItems++;\n }\n } else {\n // Handle primitive values\n if (visibleItems > 0) {\n result += ',\\n';\n }\n\n switch (child.type) {\n case DiffType.ADDED:\n result += color\n ? `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}+ ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.REMOVED:\n result += color\n ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}`\n : `${innerIndent}- ${formatPrimitive(child.oldValue)}`;\n visibleItems++;\n break;\n case DiffType.UNCHANGED:\n // Special handling for ignored values (when using ignoreValues: true)\n if (child.meta?.ignored && child.path) {\n result += color\n ? `${innerIndent}${colors.gray} ${child.path[child.path.length - 1] || ''}${colors.reset}`\n : `${innerIndent} ${child.path[child.path.length - 1] || ''}`;\n } else {\n result += color\n ? `${innerIndent}${colors.gray} ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent} ${formatPrimitive(child.newValue)}`;\n }\n visibleItems++;\n break;\n case DiffType.CHANGED:\n result += color\n ? `${innerIndent}${colors.red}- ${formatPrimitive(child.oldValue)}${colors.reset}\\n` +\n `${innerIndent}${colors.green}+ ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}- ${formatPrimitive(child.oldValue)}\\n` +\n `${innerIndent}+ ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n }\n }\n }\n }\n\n if (visibleItems > 0) {\n result += '\\n';\n }\n result += `${baseIndent}]`;\n return result;\n}\n\n/**\n * Format object diffs with proper indentation and Git-style markers\n */\nfunction formatObjectDiff(\n diff: DiffResult,\n options: DiffOptions,\n indent: number = 0,\n): string {\n const { color = true, full = false } = options;\n const baseIndent = ' '.repeat(indent);\n const innerIndent = ' '.repeat(indent + 2);\n let result = `{\\n`;\n let visibleItems = 0;\n\n if (diff.children) {\n // First, filter out children that won't be displayed\n const displayableChildren = diff.children.filter((child) => {\n if (child.type !== DiffType.UNCHANGED) return true;\n if (full) return true;\n if (child.children && child.children.length > 0) return true;\n const key = child.path?.[child.path.length - 1] || '';\n if (options.outputKeys?.includes(key)) return true;\n return false;\n });\n\n for (let i = 0; i < displayableChildren.length; i++) {\n const child = displayableChildren[i];\n const key = child.path?.[child.path.length - 1] || '';\n const isLast = i === displayableChildren.length - 1;\n\n // If we already added an item, and we're not at a new line, add a comma and new line\n if (visibleItems > 0 && !result.endsWith('\\n')) {\n result += ',\\n';\n }\n\n if (child.children && child.children.length > 0) {\n // Handle nested objects/arrays\n const nestedContent = Array.isArray(child.newValue || child.oldValue)\n ? formatArrayDiff(child, options, indent + 2)\n : formatObjectDiff(child, options, indent + 2);\n\n // Only add if there's actual content in the nested structure\n if (nestedContent.trim().length > 2) {\n // More than just '{}' or '[]'\n result += `${innerIndent}${key}: ${nestedContent}`;\n visibleItems++;\n }\n } else {\n // Handle primitive values\n switch (child.type) {\n case DiffType.ADDED:\n result += color\n ? `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.REMOVED:\n result += color\n ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}`\n : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}`;\n visibleItems++;\n break;\n case DiffType.CHANGED:\n result += color\n ? `${innerIndent}${colors.red}- ${key}: ${formatPrimitive(child.oldValue)}${colors.reset}\\n` +\n `${innerIndent}${colors.green}+ ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent}- ${key}: ${formatPrimitive(child.oldValue)}\\n` +\n `${innerIndent}+ ${key}: ${formatPrimitive(child.newValue)}`;\n visibleItems++;\n break;\n case DiffType.UNCHANGED:\n if (full || options.outputKeys?.includes(key)) {\n // Special handling for ignored values (when using ignoreValues: true)\n if (child.meta?.ignored) {\n result += color\n ? `${innerIndent}${colors.gray} ${key}${colors.reset}`\n : `${innerIndent} ${key}`;\n } else {\n result += color\n ? `${innerIndent}${colors.gray} ${key}: ${formatPrimitive(child.newValue)}${colors.reset}`\n : `${innerIndent} ${key}: ${formatPrimitive(child.newValue)}`;\n }\n visibleItems++;\n }\n break;\n }\n }\n\n // Add comma if not the last item and not already ending with newline\n if (!isLast && !result.endsWith('\\n')) {\n result += ',';\n }\n\n // Always ensure we end with a newline before the next item\n if (!result.endsWith('\\n')) {\n result += '\\n';\n }\n }\n }\n\n // Only add final newline if we have content\n if (visibleItems > 0 && !result.endsWith('\\n')) {\n result += '\\n';\n }\n\n result += `${baseIndent}}`;\n return result;\n}\n\n/**\n * Get the prefix for a diff type\n */\nfunction getPrefix(type: DiffType | string): string {\n switch (type) {\n case DiffType.ADDED:\n return '+';\n case DiffType.REMOVED:\n return '-';\n case DiffType.CHANGED:\n return '!';\n default:\n return ' ';\n }\n}\n\n/**\n * Format a primitive value for output\n */\nfunction formatPrimitive(value: any): string {\n if (value === undefined) {\n return 'undefined';\n }\n\n if (value === null) {\n return 'null';\n }\n\n if (typeof value === 'string') {\n // Use JavaScript object notation with single quotes\n return `'${value}'`;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n\n // For objects and arrays, use properly formatted JavaScript object notation\n if (typeof value === 'object') {\n const json = JSON.stringify(value, null, 2);\n return json;\n }\n\n return String(value);\n}\n","import { createDiff } from './diff';\nimport { formatDiff } from './formatter';\nimport { DiffOptions, DiffResult, DiffType, SerializableValue } from './types';\n\n/**\n * Compare two values and generate a detailed diff result object\n *\n * @param oldValue - Original value to compare from\n * @param newValue - New value to compare against\n * @param options - Configuration options for the diff\n * @returns A structured diff result object\n */\nexport function diffRaw(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n): DiffResult {\n return createDiff(oldValue, newValue, options);\n}\n\n/**\n * Compare two values and generate a formatted diff string\n *\n * @param oldValue - Original value to compare from\n * @param newValue - New value to compare against\n * @param options - Configuration options for the diff\n * @returns A formatted string representation of the diff\n */\nexport function diff(\n oldValue: SerializableValue,\n newValue: SerializableValue,\n options: DiffOptions = {},\n): string {\n const diffResult = diffRaw(oldValue, newValue, options);\n return formatDiff(diffResult, options);\n}\n\n// Export types\nexport type { DiffOptions, DiffResult, SerializableValue };\nexport { DiffType };\n"],"mappings":"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","names":["DiffType","children","diff"]}
|