@prismicio/types-internal
Version:
Prismic types for Custom Types and Prismic Data
78 lines (66 loc) • 1.92 kB
text/typescript
import { Arrays, Objects } from "../../utils"
import type { SharedSlice, Variation } from "../widgets/slices"
import { type DiffChange, DiffOperation } from "./Changes"
import { VariationComparator, VariationDiff } from "./Variation"
export type SliceMetadata = Omit<SharedSlice, "variations">
export type SliceDiff = DiffChange<
SharedSlice,
Partial<
SliceMetadata & {
variations?: Partial<Record<string, VariationDiff>>
}
>
>
function compareSliceMeta(
sliceA?: SharedSlice,
sliceB?: SharedSlice,
): Partial<SliceMetadata> {
const zippedSlices = Objects.zipObjects(sliceA, sliceB)
return Object.entries(zippedSlices).reduce((acc, [key, value]) => {
if (key === `variations`) return acc
if (value?.left === value?.right) return acc
return { ...acc, [key]: value?.right }
}, {})
}
export const SliceComparator = {
compare(sliceA?: SharedSlice, sliceB?: SharedSlice): SliceDiff | undefined {
if (!sliceA && sliceB)
return {
op: DiffOperation.Added,
value: sliceB,
}
if (sliceA && !sliceB)
return {
op: DiffOperation.Removed,
}
const diffMeta = compareSliceMeta(sliceA, sliceB)
const zippedSlices = Objects.zipObjects<Variation>(
sliceA && Arrays.toRecord(sliceA.variations, (v) => v.id),
sliceB && Arrays.toRecord(sliceB.variations, (v) => v.id),
)
const diffVariations = Object.entries(zippedSlices).reduce<
Partial<Record<string, VariationDiff>>
>((acc, [variationId, value]) => {
if (!value) return acc
const vDiff = VariationComparator.compare(value.left, value.right)
if (!vDiff) return acc
return {
...acc,
[variationId]: vDiff,
}
}, {})
const diffSlice = {
...diffMeta,
...(Objects.isNotEmpty(diffVariations)
? { variations: diffVariations }
: {}),
}
if (Objects.isNotEmpty(diffSlice)) {
return {
op: DiffOperation.Updated,
value: diffSlice,
}
}
return undefined
},
}