UNPKG

@prismicio/types-internal

Version:
131 lines (119 loc) 3 kB
import { isRight } from "fp-ts/lib/Either" import * as t from "io-ts" import { v4 as uuid, validate as validateUuid } from "uuid" import type { CompositeSlice, Group, NestableWidget, StaticSlices, UID, VariationFields, } from "../customtypes" import { FieldContentType, FieldType, SharedSliceItemContent, SliceItemContent, WidgetContent, } from "./fields" type WithFieldType = WithContentType & { type: FieldType } export function hasFieldContentType(obj: unknown): obj is WithFieldType { return ( hasContentType(obj) && obj.__TYPE__ === FieldContentType && (obj as WithFieldType)?.type !== undefined && typeof (obj as WithFieldType).type === "string" && isRight(FieldType.decode((obj as WithFieldType).type)) ) } type WithContentType = { __TYPE__: string } export function hasContentType(obj: unknown): obj is WithContentType { return typeof obj === "object" && obj !== null && "__TYPE__" in obj } const isUuid = (input: unknown): input is string => typeof input === "string" && validateUuid(input) const uuidWithFallback = new t.Type<string, string, unknown>( "UUID", isUuid, (u, c) => { if (typeof u === "undefined") return t.success(uuid()) if (isUuid(u)) return t.success(u) return t.failure(u, c) }, t.identity, ) export function withKey<C extends t.Mixed>(codec: C) { return t.intersection([t.strict({ key: uuidWithFallback }), codec]) } export type TraverseSliceContentFn = < S extends SliceItemContent | SharedSliceItemContent, D extends VariationFields | CompositeSlice | Group | NestableWidget, >({ path, key, apiId, model, content, }: { path: ContentPath key: string apiId: string model?: D | undefined content: S }) => S | SharedSliceItemContent | undefined export type TraverseWidgetContentFn< ContentTransformMode extends "preserve" | "widen" = "preserve", > = < C extends WidgetContent, D extends NestableWidget | StaticSlices | Group | UID, >({ path, key, apiId, model, content, }: { path: ContentPath key: string apiId: string model?: D | undefined content: C }) => | ([ContentTransformMode] extends ["preserve"] ? C : WidgetContent) | undefined export type ContentPathEntry = { type: | "CustomType" | "Widget" | "SharedSlice" | "Slice" | "LegacySlice" | "GroupItem" | "primary" | "items" | "RepeatableItem" key: string } export type ContentPath = ReadonlyArray<ContentPathEntry> const PATH_SEPARATOR = "::" export const ContentPath = { serialize(path: ContentPath): string { return path.map((entry) => entry.key).join(PATH_SEPARATOR) }, current(path: ContentPath): ContentPathEntry | undefined { return path[path.length - 1] }, append(path: string, strElement: string): string { return path + PATH_SEPARATOR + strElement }, make( entries: Array<{ key?: ContentPathEntry["key"] | undefined type: ContentPathEntry["type"] }>, ): ContentPath { return entries.reduce<ContentPath>((acc, { key, type }) => { return key ? acc.concat({ key, type }) : acc }, []) }, }