UNPKG

@prismicio/types-internal

Version:
99 lines (89 loc) 2.34 kB
import * as t from "io-ts" import { WidgetKey } from "../common" import type { Fields } from "../utils" import { Group, NestableWidget, NestedGroup, traverseGroup, traverseSlices, UID, } from "./widgets" import type { SharedSlice } from "./widgets/slices" import { DynamicWidget, StaticWidget, Widgets } from "./widgets/Widget" export function sectionReader<T extends StaticWidget | DynamicWidget>( codec: t.Type<T, unknown>, ) { return t.record(WidgetKey, codec) // WidgetId -> Widget Data } export const StaticSection = sectionReader(StaticWidget) export type StaticSection = t.TypeOf<typeof StaticSection> export const DynamicSection = sectionReader(DynamicWidget) export type DynamicSection = t.TypeOf<typeof DynamicSection> export const Sections = { toStatic( dynamic: DynamicSection, sharedSlices: Map<string, SharedSlice>, ): StaticSection { const section = Object.entries(dynamic).reduce( ( acc: { [key: string]: StaticWidget }, [widgetKey, widget]: [string, DynamicWidget], ) => { return { ...acc, [widgetKey]: Widgets.toStatic(widget, sharedSlices) } }, {}, ) return section as StaticSection }, } export function traverseSection< T extends DynamicSection | StaticSection, >(args: { path: ReadonlyArray<string> section: T onField: Fields.OnFieldFn<UID | NestableWidget | Group | NestedGroup> }): T { const { path: prevPath, section: prevSection, onField } = args let section: T | undefined for (const [key, prevModel] of Object.entries(prevSection)) { const path = [...prevPath, key] let model switch (prevModel.type) { case "Choice": case "Slices": model = traverseSlices({ path, slices: prevModel, onField: onField as Fields.OnFieldFn< NestableWidget | Group | NestedGroup >, }) break case "Group": model = onField({ path, key, field: traverseGroup({ path, group: prevModel, onField: onField as Fields.OnFieldFn<NestableWidget | NestedGroup>, }), }) break default: model = onField({ path, key, field: prevModel, }) break } if (model !== prevModel) { if (!section) section = { ...prevSection } section[key] = model } } // returns the traversed model instead of a new one if it didn't change return section ?? prevSection }