import _ from 'lodash'; import type { ArrayDifference, Difference, ObjectDifference } from '../json-diff.types'; import { useCopy } from '@/composable/copy'; export function DiffRootViewer({ diff }: { diff: Difference }) { return (
); } function 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 }); } function 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 })} ,
  • ); } function ComparisonViewer({ diff, showKeys }: { diff: Difference; showKeys?: boolean }) { const { value, key, oldValue } = diff; return (
  • {showKeys && ( <> {key} {': '} )} {Value({ value: oldValue, status: 'removed' })} {Value({ value, status: 'added' })},
  • ); } function 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); } function Value({ value, status }: { value: unknown; status: string }) { const formatedValue = formatValue(value); const { copy } = useCopy({ source: formatedValue }); return ( {formatedValue} ); }