import type * as RawApiTypes from '../generated/RawApiTypes.js';
import type { ItemTypeDefinition, ToItemAttributesInRequest } from '../utilities/itemDefinition.js';
import { type LocalizedFieldValue } from '../utilities/normalizedFieldValues.js';
import type { FramedSingleBlockEditorConfiguration } from './appearance/framed_single_block.js';
import type { FramelessSingleBlockEditorConfiguration } from './appearance/frameless_single_block.js';
import type { RequiredValidator } from './validators/required.js';
import type { SingleBlockBlocksValidator } from './validators/single_block_blocks.js';
/**
 * SINGLE BLOCK FIELD TYPE SYSTEM FOR DATOCMS
 *
 * This module defines a comprehensive type system for handling DatoCMS Single Block fields,
 * which contain a single embedded content block.
 *
 * The challenge we're solving:
 * - DatoCMS Single Block fields contain a single "block" (embedded content item)
 * - By default, API responses contain blocks as string IDs (lightweight references)
 * - With ?nested=true parameter, API responses contain blocks as full block objects
 *   (which in turn can contain other blocks)
 * - For API requests, blocks can be represented as:
 *   1. String IDs (referencing existing blocks)
 *   2. Full block objects with IDs (for updates)
 *   3. Block objects without IDs (for creation)
 *
 * This creates a need for different type variants for the same conceptual data structure.
 */
/**
 * =============================================================================
 * BASIC SINGLE BLOCK TYPE - Default API response format
 * =============================================================================
 *
 * The standard Single Block field value containing a block reference as string ID.
 * This is what you get from regular API responses without ?nested=true.
 */
/**
 * Basic Single Block field value - string block ID (lightweight reference)
 */
export type SingleBlockFieldValue = string | null;
/**
 * =============================================================================
 * REQUEST VARIANT - Type for sending data TO the DatoCMS API
 * =============================================================================
 *
 * When making API requests, we need flexibility in how we represent embedded blocks:
 * - Use string ID to reference existing block that does not need to change
 * - Include full block object for updates
 * - Omit ID for new blocks being created
 */
/** Represents an existing block in a CMA request */
export type UnchangedBlockInRequest = RawApiTypes.ItemIdentity;
/** Represents a block we want to update in a CMA request */
export type UpdatedBlockInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = {
    __itemTypeId?: D['itemTypeId'];
    type: RawApiTypes.ItemType1;
    id: RawApiTypes.ItemIdentity;
    relationships?: RawApiTypes.ItemRelationships<D>;
    meta?: RawApiTypes.ItemMeta;
    attributes: ToItemAttributesInRequest<D>;
};
/** Represents a new block to create in a CMA request */
export type NewBlockInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = {
    __itemTypeId?: D['itemTypeId'];
    type: RawApiTypes.ItemType1;
    relationships: RawApiTypes.ItemRelationships<D>;
    meta?: RawApiTypes.ItemMeta;
    attributes: ToItemAttributesInRequest<D>;
};
/**
 * Union type representing the different ways a block can be specified in API requests:
 * - string: Just the block ID (to keep existing blocks unchanged)
 * - Full block object with ID (to update an existing block)
 * - Block object without ID (to create a new block)
 *
 * Also, 'meta' can always be omitted
 */
export type BlockInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = [
    D
] extends [never] ? UnchangedBlockInRequest : D extends unknown ? UnchangedBlockInRequest | UpdatedBlockInRequest<D> | NewBlockInRequest<D> : never;
export type BlockInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition> = RawApiTypes.ItemInNestedResponse<D>;
/**
 * Single Block field value for API requests - allows flexible block representations:
 * - string: Just the block ID (to keep existing blocks unchanged)
 * - Full block object with ID (to update an existing block)
 * - Block object without ID (to create a new block)
 */
export type SingleBlockFieldValueInRequest<D extends ItemTypeDefinition = ItemTypeDefinition> = BlockInRequest<D> | null;
/**
 * =============================================================================
 * NESTED VARIANT - Type for API responses with ?nested=true parameter
 * =============================================================================
 *
 * When using the ?nested=true query parameter, the API returns Single Block data
 * with embedded block fully populated as complete RawApiTypes.Item object instead
 * of just string ID. This provides type safety for working with fully resolved data.
 */
/**
 * Single Block field value with nested block - fully populated block object
 */
export type SingleBlockFieldValueInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition> = BlockInNestedResponse<D> | null;
/**
 * =============================================================================
 * SHARED UTILITY FUNCTIONS
 * =============================================================================
 * These functions are used internally and can be imported by other modules
 */
/**
 * Validates if the input is a valid item (either block or record) ID
 */
export declare function isItemId(input: unknown): input is string;
export type ItemWithOptionalIdAndMeta<D extends ItemTypeDefinition = ItemTypeDefinition> = D extends any ? OptionalFields<RawApiTypes.Item<D>, 'id' | 'meta'> : never;
/**
 * Validates if the input is a RawApiTypes.Item object (with optional `id` and `meta`)
 */
export declare function isItemWithOptionalIdAndMeta<D extends ItemTypeDefinition = ItemTypeDefinition>(block: unknown): block is ItemWithOptionalIdAndMeta<D>;
export type ItemWithOptionalMeta<D extends ItemTypeDefinition = ItemTypeDefinition> = D extends any ? OptionalFields<RawApiTypes.Item<D>, 'meta'> : never;
/**
 * Validates if the input is a a complete RawApiTypes.Item object with optional `meta`
 */
export declare function isItemWithOptionalMeta<D extends ItemTypeDefinition = ItemTypeDefinition>(block: unknown): block is ItemWithOptionalMeta<D>;
/**
 * =============================================================================
 * TYPE GUARDS - Runtime validation functions
 * =============================================================================
 */
/**
 * Type guard for basic Single Block field values (block as string ID only).
 * Checks for string structure and ensures block is a string reference.
 */
export declare function isSingleBlockFieldValue(value: unknown): value is SingleBlockFieldValue;
export declare function isLocalizedSingleBlockFieldValue(value: unknown): value is LocalizedFieldValue<SingleBlockFieldValue>;
/**
 * Shape check for a block object on the *request* side. Accepts every object
 * form the CMA allows inside a request payload:
 *
 *   1. New block (no id, full body):
 *        { type: 'item', attributes, relationships: { item_type } }
 *   2. Updated block, full body:
 *        { type: 'item', id, attributes, relationships: { item_type } }
 *   3. Updated block, id-only (patch some attributes of an existing block):
 *        { type: 'item', id, attributes }                       ← no relationships
 *
 * Case 3 is what `buildBlockRecord` produces when the caller omits
 * `item_type` — the server derives the model from the existing block's id,
 * so re-specifying it in `relationships` is redundant.
 */
export declare function isBlockObjectInRequest(block: unknown): block is {
    type: RawApiTypes.ItemType1;
    attributes: Record<string, unknown>;
};
/**
 * Type guard for Single Block field values in API request format.
 * Allows block as string ID, full object with ID, or object without ID.
 */
export declare function isSingleBlockFieldValueInRequest<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is SingleBlockFieldValueInRequest<D>;
export declare function isLocalizedSingleBlockFieldValueInRequest<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is LocalizedFieldValue<SingleBlockFieldValueInRequest<D>>;
/**
 * Type guard for Single Block field values with nested blocks (?nested=true format).
 * Ensures block is a full RawApiTypes.Item object with complete data.
 */
export declare function isSingleBlockFieldValueInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is SingleBlockFieldValueInNestedResponse<D>;
export declare function isLocalizedSingleBlockFieldValueInNestedResponse<D extends ItemTypeDefinition = ItemTypeDefinition>(value: unknown): value is LocalizedFieldValue<SingleBlockFieldValueInNestedResponse<D>>;
export type SingleBlockFieldValidators = {
    /** Only accept references to block records of the specified block models */
    single_block_blocks: SingleBlockBlocksValidator;
    /** Value must be specified or it won't be valid */
    required?: RequiredValidator;
};
export type SingleBlockFieldAppearance = {
    editor: 'framed_single_block';
    parameters: FramedSingleBlockEditorConfiguration;
} | {
    editor: 'frameless_single_block';
    parameters: FramelessSingleBlockEditorConfiguration;
} | {
    /** Plugin ID */
    editor: string;
    /** Plugin configuration */
    parameters: Record<string, unknown>;
};
type OptionalFields<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
export {};
