import _ from 'lodash'; import { useCopy } from '@/composable/copy'; import type { Difference, ArrayDifference, ObjectDifference } from '../json-diff.types'; export const DiffRootViewer = ({ diff }: { diff: Difference }) => { return (
); }; const DiffViewer = ({ diff, showKeys = true }: { diff: Difference; showKeys?: boolean }) => { const { type, status } = diff; if (status === 'updated') { return ComparisonViewer({ diff, showKeys }); } if (type === 'array') { return ChildrenViewer({ diff, showKeys, showChildrenKeys: false, openTag: '[', closeTag: ']' }); } if (type === 'object') { return ChildrenViewer({ diff, showKeys, openTag: '{', closeTag: '}' }); } return LineDiffViewer({ diff, showKeys }); }; const LineDiffViewer = ({ diff, showKeys }: { diff: Difference; showKeys?: boolean }) => { const { value, key, status, oldValue } = diff; const valueToDisplay = status === 'removed' ? oldValue : value; return (
  • {showKeys && ( <> {key} {': '} )} {Value({ value: valueToDisplay, status })} ,
  • ); }; const ComparisonViewer = ({ diff, showKeys }: { diff: Difference; showKeys?: boolean }) => { const { value, key, oldValue } = diff; return (
  • {showKeys && ( <> {key} {': '} )} {Value({ value: oldValue, status: 'removed' })} {Value({ value, status: 'added' })},
  • ); }; const ChildrenViewer = ({ diff, openTag, closeTag, showKeys, showChildrenKeys = true, }: { diff: ArrayDifference | ObjectDifference; showKeys: boolean; showChildrenKeys?: boolean; openTag: string; closeTag: string; }) => { const { children, key, status, type } = diff; return (
  • {showKeys && ( <> {key} {': '} )} {openTag} {children.length > 0 && } {closeTag + ','}
  • ); }; function formatValue(value: unknown) { if (_.isNull(value)) { return 'null'; } return JSON.stringify(value); } const Value = ({ value, status }: { value: unknown; status: string }) => { const formatedValue = formatValue(value); const { copy } = useCopy({ source: formatedValue }); return ( {formatedValue} ); };