import { isEqual } from 'lodash'; /** * Helper function to check if a value has changed compared to the old value. * Uses deep equality comparison for arrays and objects. * * Key behaviors: * - `undefined` = field not provided (returns false) * - `null` = explicit value (returns true if different from oldVal) * - Empty values (`[]`, `{}`, `''`) are valid changes if oldVal differs * * @param newVal - The new value to check * @param oldVal - The old value to compare against * @returns true if the value has changed, false otherwise */ export default function hasChanged(newVal: any, oldVal: any): boolean { // undefined means the field was not provided in the update request // This is distinct from null, which is an explicit value if (newVal === undefined) return false; // Early return for strict equality (handles primitives and same references) // This handles: null === null, 0 === 0, false === false, etc. if (newVal === oldVal) return false; // null is an explicit value - if we get here, newVal is null but oldVal is not // (or vice versa), which means the value has changed if (newVal === null || oldVal === null) return true; // Use lodash isEqual for deep equality comparison // This handles arrays, objects, and nested structures correctly if ( Array.isArray(newVal) || (typeof newVal === 'object' && newVal !== null) ) { return !isEqual(newVal, oldVal); } // All other cases: primitive values that are different return true; }