UNPKG

@datocms/cma-client

Version:
124 lines (123 loc) 7.78 kB
import { type Block, type Document, type InlineBlock } from 'datocms-structured-text-utils'; import type { ItemTypeDefinition } from '../utilities/itemDefinition'; import { type LocalizedFieldValue } from '../utilities/normalizedFieldValues'; import type { StructuredTextEditorConfiguration } from './appearance/structured_text'; import { type BlockInNestedResponse, type BlockInRequest } from './single_block'; import type { RequiredValidator } from './validators'; import type { LengthValidator } from './validators/length'; import type { StructuredTextBlocksValidator } from './validators/structured_text_blocks'; import type { StructuredTextInlineBlocksValidator } from './validators/structured_text_inline_blocks'; import type { StructuredTextLinksValidator } from './validators/structured_text_links'; /** * STRUCTURED TEXT TYPE SYSTEM FOR DATOCMS * * This module defines a comprehensive type system for handling DatoCMS structured text fields, * which are rich text documents that can contain embedded blocks and inline elements. * * The challenge we're solving: * - DatoCMS structured text can contain "blocks" (embedded content items) in bloth 'block' * and 'inlineBlock' nodes * - By default, CMA responses contain blocks as string IDs (lightweight references) * - With ?nested=true parameter though, API responses contain blocks as full item objects * (which in turn can contain other blocks) * - For CMA requests, blocks can be represented as: * 1. String IDs (referencing existing items) * 2. Full item objects with IDs (for updates) * 3. Item objects without IDs (for creation) * * This creates a need for different type variants for the same conceptual data structure. */ /** * ============================================================================= * REQUEST VARIANTS - Types for sending data TO the DatoCMS API * ============================================================================= * * When making API requests, we need flexibility in how we represent embedded blocks: * - Use string IDs to reference existing blocks that do not need to change * - Include full block objects for updates * - Omit IDs for new blocks being created */ /** * Variant of 'block' structured text node for API requests */ export type BlockNodeInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = Block<BlockInRequest<D>>; /** * Variant of 'inlineBlock' structured text node for API requests */ export type InlineBlockNodeInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = InlineBlock<BlockInRequest<D>>; /** * Variant of Structured Text document for API requests */ export type DocumentInRequest<BlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition, InlineBlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition> = Document<BlockInRequest<BlockItemTypeDefinition>, BlockInRequest<InlineBlockItemTypeDefinition>>; /** * ============================================================================= * NESTED VARIANTS - Types for API responses with ?nested=true parameter * ============================================================================= * * When using the GET /items?nested=true, the CMA returns Structured Text documents * with embedded blocks fully populated as complete RawApiTypes.Item objects instead * of just string IDs. */ /** * Variant of 'block' structured text node for ?nested=true API responses */ export type BlockNodeInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition> = Block<BlockInNestedResponse<D>>; /** * Variant of 'inlineBlock' structured text node for ?nested=true API responses */ export type InlineBlockNodeInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition> = InlineBlock<BlockInNestedResponse<D>>; /** * Variant of Structured Text document for ?nested=true API responses */ export type DocumentInNestedResponse<BlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition, InlineBlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition> = Document<BlockInNestedResponse<BlockItemTypeDefinition>, BlockInNestedResponse<InlineBlockItemTypeDefinition>>; /** * ============================================================================= * MAIN APPLICATION TYPES * ============================================================================= */ /** * The main type for structured text field values in our application. * Can be null (empty field) or a document with blocks as string IDs */ export type StructuredTextFieldValue = Document | null; export type StructuredTextFieldValueInRequest<BlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition, InlineBlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition> = DocumentInRequest<BlockItemTypeDefinition, InlineBlockItemTypeDefinition> | null; export type StructuredTextFieldValueInNestedResponse<BlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition, InlineBlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition> = DocumentInNestedResponse<BlockItemTypeDefinition, InlineBlockItemTypeDefinition> | null; /** * Type guard for basic structured text field values (blocks as string IDs only). * Checks for the expected structure and ensures all block/inlineBlock nodes have string IDs. */ export declare function isStructuredTextFieldValue(value: unknown): value is StructuredTextFieldValue; export declare function isLocalizedStructuredTextFieldValue(value: unknown): value is LocalizedFieldValue<StructuredTextFieldValue>; /** * Type guard for structured text field values in API request format. * Allows blocks as string IDs, full objects with IDs, or objects without IDs. */ export declare function isStructuredTextFieldValueInRequest<BlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition, InlineBlockItemTypeDefinition extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is StructuredTextFieldValueInRequest<BlockItemTypeDefinition, InlineBlockItemTypeDefinition>; export declare function isLocalizedStructuredTextFieldValueInRequest<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is LocalizedFieldValue<StructuredTextFieldValueInRequest<D>>; /** * Type guard for structured text field values with nested blocks (?nested=true format). * Ensures all block/inlineBlock nodes have full RawApiTypes.Item objects. */ export declare function isStructuredTextFieldValueInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is StructuredTextFieldValueInNestedResponse<D>; export declare function isLocalizedStructuredTextFieldValueInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is LocalizedFieldValue<StructuredTextFieldValueInNestedResponse<D>>; export type StructuredTextFieldValidators = { /** Value must be specified or it won't be valid */ required?: RequiredValidator; /** Only accept references to block records of the specified block models */ structured_text_blocks: StructuredTextBlocksValidator; /** Only accept itemLink to inlineItem nodes for records of the specified models */ structured_text_links: StructuredTextLinksValidator; /** Accept strings only with a specified number of characters */ length?: LengthValidator; /** Only accept references to block records of the specified block models for inline blocks */ structured_text_inline_blocks?: StructuredTextInlineBlocksValidator; }; export type StructuredTextFieldAppearance = { editor: 'structured_text'; parameters: StructuredTextEditorConfiguration; } | { /** Plugin ID */ editor: string; /** Plugin configuration */ parameters: Record<string, unknown>; };