mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
refactor: take chatgpt's suggestions for diff calc algorithm (#6086)
We had to make some updates to let the compiler know about the types and fix an issue with nested objects not being compared as objects (instead as strings), but this saves us a few lines and is hopefully more readable.
This commit is contained in:
parent
dbc577bfa4
commit
99b8fa2943
@ -6,22 +6,16 @@ import { IFeatureStrategy } from 'interfaces/strategy';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import omit from 'lodash.omit';
|
||||
|
||||
type JsonDiffProps = {
|
||||
snapshotValue: unknown;
|
||||
currentValue: unknown;
|
||||
changeValue: unknown;
|
||||
fallback?: unknown;
|
||||
};
|
||||
const hasJsonDiff = ({
|
||||
snapshotValue,
|
||||
currentValue,
|
||||
changeValue,
|
||||
fallback,
|
||||
}: JsonDiffProps) => {
|
||||
const currentJson = JSON.stringify(currentValue ?? fallback);
|
||||
const stringifyWithFallback = (value: unknown, fallback: unknown) =>
|
||||
JSON.stringify(value ?? fallback);
|
||||
|
||||
const hasJsonDiff =
|
||||
(fallback?: unknown) =>
|
||||
(snapshotValue: unknown, currentValue: unknown, changeValue: unknown) => {
|
||||
const currentJson = stringifyWithFallback(currentValue, fallback);
|
||||
return (
|
||||
JSON.stringify(snapshotValue ?? fallback) !== currentJson &&
|
||||
JSON.stringify(changeValue ?? fallback) !== currentJson
|
||||
stringifyWithFallback(snapshotValue, fallback) !== currentJson &&
|
||||
stringifyWithFallback(changeValue, fallback) !== currentJson
|
||||
);
|
||||
};
|
||||
|
||||
@ -36,7 +30,7 @@ const hasChanged = (
|
||||
!isEqual(currentValue, changeValue)
|
||||
);
|
||||
}
|
||||
return hasJsonDiff({ snapshotValue, currentValue, changeValue });
|
||||
return hasJsonDiff()(snapshotValue, currentValue, changeValue);
|
||||
};
|
||||
|
||||
type DataToOverwrite<Prop extends keyof ChangeRequestEditStrategy> = {
|
||||
@ -44,20 +38,44 @@ type DataToOverwrite<Prop extends keyof ChangeRequestEditStrategy> = {
|
||||
oldValue: ChangeRequestEditStrategy[Prop];
|
||||
newValue: ChangeRequestEditStrategy[Prop];
|
||||
};
|
||||
|
||||
type ChangesThatWouldBeOverwritten = DataToOverwrite<
|
||||
keyof ChangeRequestEditStrategy
|
||||
>[];
|
||||
|
||||
const removeEmptyEntries = (
|
||||
change: unknown,
|
||||
): change is DataToOverwrite<keyof ChangeRequestEditStrategy> =>
|
||||
Boolean(change);
|
||||
|
||||
const getChangedProperty = (
|
||||
key: keyof ChangeRequestEditStrategy,
|
||||
currentValue: unknown,
|
||||
snapshotValue: unknown,
|
||||
changeValue: unknown,
|
||||
) => {
|
||||
const fallbacks = { segments: [], variants: [], title: '' };
|
||||
const fallback = fallbacks[key as keyof typeof fallbacks] ?? undefined;
|
||||
const diffCheck = key in fallbacks ? hasJsonDiff(fallback) : hasChanged;
|
||||
|
||||
const changeInfo = {
|
||||
property: key as keyof ChangeRequestEditStrategy,
|
||||
oldValue: currentValue,
|
||||
newValue: changeValue,
|
||||
};
|
||||
|
||||
return diffCheck(snapshotValue, currentValue, changeValue)
|
||||
? changeInfo
|
||||
: undefined;
|
||||
};
|
||||
|
||||
export const getChangesThatWouldBeOverwritten = (
|
||||
currentStrategyConfig: IFeatureStrategy | undefined,
|
||||
change: IChangeRequestUpdateStrategy,
|
||||
): ChangesThatWouldBeOverwritten | null => {
|
||||
const { snapshot } = change.payload;
|
||||
if (!snapshot || !currentStrategyConfig) return null;
|
||||
|
||||
if (snapshot && currentStrategyConfig) {
|
||||
// compare each property in the snapshot. The property order
|
||||
// might differ, so using JSON.stringify to compare them
|
||||
// doesn't work.
|
||||
const changes: ChangesThatWouldBeOverwritten = Object.entries(
|
||||
omit(currentStrategyConfig, 'strategyName'),
|
||||
)
|
||||
@ -66,68 +84,19 @@ export const getChangesThatWouldBeOverwritten = (
|
||||
const changeValue =
|
||||
change.payload[key as keyof ChangeRequestEditStrategy];
|
||||
|
||||
const hasJsonDiffWithFallback = (fallback: unknown) =>
|
||||
hasJsonDiff({
|
||||
snapshotValue,
|
||||
return getChangedProperty(
|
||||
key as keyof ChangeRequestEditStrategy,
|
||||
currentValue,
|
||||
snapshotValue,
|
||||
changeValue,
|
||||
fallback,
|
||||
});
|
||||
|
||||
// compare, assuming that order never changes
|
||||
if (key === 'segments') {
|
||||
// segments can be undefined on the original
|
||||
// object, but that doesn't mean it has changed
|
||||
if (hasJsonDiffWithFallback([])) {
|
||||
return {
|
||||
property: key as keyof ChangeRequestEditStrategy,
|
||||
oldValue: currentValue,
|
||||
newValue: changeValue,
|
||||
};
|
||||
}
|
||||
} else if (key === 'variants') {
|
||||
// strategy variants might not be defined, so use
|
||||
// fallback values
|
||||
if (hasJsonDiffWithFallback([])) {
|
||||
return {
|
||||
property: key as keyof ChangeRequestEditStrategy,
|
||||
oldValue: currentValue,
|
||||
newValue: changeValue,
|
||||
};
|
||||
}
|
||||
} else if (key === 'title') {
|
||||
// the title can be defined as `null` or
|
||||
// `undefined`, so we fallback to an empty string
|
||||
if (hasJsonDiffWithFallback('')) {
|
||||
return {
|
||||
property: key as keyof ChangeRequestEditStrategy,
|
||||
oldValue: currentValue,
|
||||
newValue: changeValue,
|
||||
};
|
||||
}
|
||||
} else if (
|
||||
hasChanged(snapshotValue, currentValue, changeValue)
|
||||
) {
|
||||
return {
|
||||
property: key as keyof ChangeRequestEditStrategy,
|
||||
oldValue: currentValue,
|
||||
newValue: changeValue,
|
||||
};
|
||||
}
|
||||
})
|
||||
.filter(
|
||||
(
|
||||
change,
|
||||
): change is DataToOverwrite<keyof ChangeRequestEditStrategy> =>
|
||||
Boolean(change),
|
||||
);
|
||||
})
|
||||
.filter(removeEmptyEntries);
|
||||
|
||||
if (changes.length) {
|
||||
// we have changes that would be overwritten
|
||||
changes.sort((a, b) => a.property.localeCompare(b.property));
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user