Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
json.js79 linesDownload Raw Back to diff
1import Diff from './base.js';
2import { tokenize } from './line.js';
3class JsonDiff extends Diff {
4    constructor() {
5        super(...arguments);
6        this.tokenize = tokenize;
7    }
8    get useLongestToken() {
9        // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a
10        // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:
11        return true;
12    }
13    castInput(value, options) {
14        const { undefinedReplacement, stringifyReplacer = (k, v) => typeof v === 'undefined' ? undefinedReplacement : v } = options;
15        return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, '  ');
16    }
17    equals(left, right, options) {
18        return super.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'), options);
19    }
20}
21export const jsonDiff = new JsonDiff();
22export function diffJson(oldStr, newStr, options) {
23    return jsonDiff.diff(oldStr, newStr, options);
24}
25// This function handles the presence of circular references by bailing out when encountering an
26// object that is already on the "stack" of items being processed. Accepts an optional replacer
27export function canonicalize(obj, stack, replacementStack, replacer, key) {
28    stack = stack || [];
29    replacementStack = replacementStack || [];
30    if (replacer) {
31        obj = replacer(key === undefined ? '' : key, obj);
32    }
33    let i;
34    for (i = 0; i < stack.length; i += 1) {
35        if (stack[i] === obj) {
36            return replacementStack[i];
37        }
38    }
39    let canonicalizedObj;
40    if ('[object Array]' === Object.prototype.toString.call(obj)) {
41        stack.push(obj);
42        canonicalizedObj = new Array(obj.length);
43        replacementStack.push(canonicalizedObj);
44        for (i = 0; i < obj.length; i += 1) {
45            canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i));
46        }
47        stack.pop();
48        replacementStack.pop();
49        return canonicalizedObj;
50    }
51    if (obj && obj.toJSON) {
52        obj = obj.toJSON();
53    }
54    if (typeof obj === 'object' && obj !== null) {
55        stack.push(obj);
56        canonicalizedObj = {};
57        replacementStack.push(canonicalizedObj);
58        const sortedKeys = [];
59        let key;
60        for (key in obj) {
61            /* istanbul ignore else */
62            if (Object.prototype.hasOwnProperty.call(obj, key)) {
63                sortedKeys.push(key);
64            }
65        }
66        sortedKeys.sort();
67        for (i = 0; i < sortedKeys.length; i += 1) {
68            key = sortedKeys[i];
69            canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack, replacer, key);
70        }
71        stack.pop();
72        replacementStack.pop();
73    }
74    else {
75        canonicalizedObj = obj;
76    }
77    return canonicalizedObj;
78}
79 
codekingpro/portable-devtools · Team Ai