import type { ContentTree } from '@financial-times/content-tree'; import { ConceptFragment, TranscriptFragment, CustomCodeComponentRichTextFragment } from '@financial-times/cp-content-pipeline-client'; import type { ContentTreeWorkarounds } from '@financial-times/cp-content-pipeline-schema'; import type { LiteralToPrimitiveDeep, SetFieldType, SetOptional, Simplify } from 'type-fest'; /** * Helper type to extend partial/undefined fields to also be null. Optional * fields in the Content Tree are represented by a partial field, but are * represented by null (abstracted by the Maybe type) in the content pipeline. */ type PartialToMaybe = Simplify<{ [K in keyof T]: Extract extends never ? T[K] : T[K] | null; }>; /** * Helper type to apply PartialToMaybe mapper type to each object field * recursively. */ type PartialToMaybeDeep = T extends object ? PartialToMaybe<{ [K in keyof T]: PartialToMaybeDeep; }> : T; /** * Helper type to convert arrays to readonly arrays. Content Tree arrays are * mutable but the arrays we return from our API are expected to be readonly. We * should explore which assumption is correct and match that in the other * declaration file. */ type ReadonlyArrays = { [K in keyof T]: ReadonlyArray; }; type ReadonlyArray = T extends Array ? readonly Item[] : T; export type TeaserConcept = PartialToMaybe>>; export type Image = PartialToMaybe>>>; export type Teaser = PartialToMaybeDeep, 'image', Omit>, 'type' | 'metaLink' | 'metaAltLink' | 'indicators' | 'image'>>>; export type Recommended = PartialToMaybe; export type RecommendedList = PartialToMaybe & { teasers?: (Teaser | null)[]; children: Recommended[]; }>>; export type ImageSetPicture = PartialToMaybe, 'images', Image[]>, 'caption' | 'credit'>>>; export type ImageSet = PartialToMaybe, 'picture'>>; export type ScrollyImage = PartialToMaybe, 'picture'>>; export type Tweet = PartialToMaybe>; type ClipFormat = 'standard-inline' | 'mobile'; interface ClipSource { audioCodec?: string; binaryUrl: string; duration?: number; mediaType: string; pixelHeight?: number; pixelWidth?: number; videoCodec?: string; quality?: string; dppx?: number; previousSourceWidth?: number; } export type Clip = PartialToMaybeDeep>; interface ClipCaption { mediaType?: string; url?: string; } type ClipTranscript = TranscriptFragment; export type ClipAccessibility = PartialToMaybeDeep>; interface ClipSetReferences { id: string; type: string; accessibility?: ClipAccessibility; noAudio?: boolean; caption?: string; credits?: string; description?: string; displayTitle?: string; systemTitle?: string; contentWarning?: string[]; source?: string; subtitle?: string; publishedDate?: string; clips?: Clip[]; fragmentIdentifier?: string | undefined; } export type ClipSet = PartialToMaybeDeep>; export type RawImage = ContentTreeWorkarounds.RawImage & { image: Image; }; export type MainImageRaw = ContentTreeWorkarounds.MainImageRaw & { image: Image; }; export type Author = PartialToMaybe; type CustomCodeComponentUI = Pick; export type CustomCodeComponent = PartialToMaybeDeep; export {};