UNPKG

@prismicio/types-internal

Version:
80 lines (68 loc) 2.17 kB
import * as t from "io-ts" import type { OnFieldFn } from "../../../_internal/utils" import { WidgetKey } from "../../../common" import { StringOrNull } from "../../../validators" import { NestableWidget } from "../nestable/NestableWidget" import type { DynamicSlice, StaticSlice } from "./Slice" export const CompositeSliceType = "Slice" export const CompositeSliceConfig = t.exact( t.partial({ label: StringOrNull, }), ) export type CompositeSliceConfig = t.TypeOf<typeof CompositeSliceConfig> export const CompositeSlice = t.exact( t.intersection([ t.type({ type: t.literal(CompositeSliceType), }), t.partial({ fieldset: StringOrNull, description: t.string, icon: t.string, display: t.string, "non-repeat": t.record(WidgetKey, NestableWidget), repeat: t.record(WidgetKey, NestableWidget), config: CompositeSliceConfig, }), ]), ) export type CompositeSlice = t.TypeOf<typeof CompositeSlice> export function isCompositeSlice( slice: DynamicSlice | StaticSlice, ): slice is CompositeSlice { return slice.type === "Slice" } export function traverseCompositeSlice(args: { path: ReadonlyArray<string> slice: CompositeSlice onField: OnFieldFn<NestableWidget> }): CompositeSlice { const { path: prevPath, slice, onField } = args let nonRepeat: Record<string, NestableWidget> | undefined for (const [key, field] of Object.entries(slice["non-repeat"] ?? {})) { const path = [...prevPath, "non-repeat", key] const newField = onField({ path, key, field }) if (field !== newField) { if (!nonRepeat) nonRepeat = { ...slice["non-repeat"] } nonRepeat[key] = newField } } let repeat: Record<string, NestableWidget> | undefined for (const [key, field] of Object.entries(slice.repeat ?? {})) { const path = [...prevPath, "repeat", key] const newField = onField({ path, key, field }) if (field !== newField) { if (!repeat) repeat = { ...slice.repeat } repeat[key] = newField } } // returns the traversed model instead of a new one if it didn't change return repeat || nonRepeat ? { ...slice, ...(nonRepeat && { "non-repeat": nonRepeat }), ...(repeat && { repeat }), } : slice }