mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 10:03:33 -06:00
* Performance: Standardize lodash imports to use destructured members Changes lodash imports of the form `import x from 'lodash/x'` to `import { x } from 'lodash'` to reduce bundle size. * Remove unnecessary _ import from Graph component * Enforce lodash import style * Fix remaining lodash imports
101 lines
2.6 KiB
TypeScript
101 lines
2.6 KiB
TypeScript
import { compare, Operation } from 'fast-json-patch';
|
|
// @ts-ignore
|
|
import jsonMap from 'json-source-map';
|
|
import { flow, get, isArray, isEmpty, last, sortBy, tail, toNumber, isNaN } from 'lodash';
|
|
|
|
export type Diff = {
|
|
op: 'add' | 'replace' | 'remove' | 'copy' | 'test' | '_get' | 'move';
|
|
value: any;
|
|
originalValue: any;
|
|
path: string[];
|
|
startLineNumber: number;
|
|
};
|
|
|
|
export type Diffs = {
|
|
[key: string]: Diff[];
|
|
};
|
|
|
|
export const jsonDiff = (lhs: any, rhs: any): Diffs => {
|
|
const diffs = compare(lhs, rhs);
|
|
const lhsMap = jsonMap.stringify(lhs, null, 2);
|
|
const rhsMap = jsonMap.stringify(rhs, null, 2);
|
|
|
|
const getDiffInformation = (diffs: Operation[]): Diff[] => {
|
|
return diffs.map((diff) => {
|
|
let originalValue = undefined;
|
|
let value = undefined;
|
|
let startLineNumber = 0;
|
|
|
|
const path = tail(diff.path.split('/'));
|
|
|
|
if (diff.op === 'replace') {
|
|
originalValue = get(lhs, path);
|
|
value = diff.value;
|
|
startLineNumber = rhsMap.pointers[diff.path].value.line;
|
|
}
|
|
if (diff.op === 'add') {
|
|
value = diff.value;
|
|
startLineNumber = rhsMap.pointers[diff.path].value.line;
|
|
}
|
|
if (diff.op === 'remove') {
|
|
originalValue = get(lhs, path);
|
|
startLineNumber = lhsMap.pointers[diff.path].value.line;
|
|
}
|
|
|
|
return {
|
|
op: diff.op,
|
|
value,
|
|
path,
|
|
originalValue,
|
|
startLineNumber,
|
|
};
|
|
});
|
|
};
|
|
|
|
const sortByLineNumber = (diffs: Diff[]) => sortBy(diffs, 'startLineNumber');
|
|
const groupByPath = (diffs: Diff[]) =>
|
|
diffs.reduce<Record<string, any>>((acc, value) => {
|
|
const groupKey: string = value.path[0];
|
|
if (!acc[groupKey]) {
|
|
acc[groupKey] = [];
|
|
}
|
|
acc[groupKey].push(value);
|
|
return acc;
|
|
}, {});
|
|
|
|
return flow([getDiffInformation, sortByLineNumber, groupByPath])(diffs);
|
|
};
|
|
|
|
export const getDiffText = (diff: Diff, showProp = true) => {
|
|
const prop = last(diff.path)!;
|
|
const propIsNumeric = isNumeric(prop);
|
|
const val = diff.op === 'remove' ? diff.originalValue : diff.value;
|
|
let text = getDiffOperationText(diff.op);
|
|
|
|
if (showProp) {
|
|
if (propIsNumeric) {
|
|
text += ` item ${prop}`;
|
|
} else {
|
|
if (isArray(val) && !isEmpty(val)) {
|
|
text += ` ${val.length} ${prop}`;
|
|
} else {
|
|
text += ` ${prop}`;
|
|
}
|
|
}
|
|
}
|
|
|
|
return text;
|
|
};
|
|
|
|
const isNumeric = (value: string) => !isNaN(toNumber(value));
|
|
|
|
export const getDiffOperationText = (operation: string): string => {
|
|
if (operation === 'add') {
|
|
return 'added';
|
|
}
|
|
if (operation === 'remove') {
|
|
return 'deleted';
|
|
}
|
|
return 'changed';
|
|
};
|