/** * Block plugin registry. Defines the runtime contract for a block type: * defaults, validation, and version migration. Editor and renderer surfaces * layer their own UI on top of these plugins via separate packages. * * Validators are hand-rolled (no zod dependency) to keep the SDK * dependency-free for browser consumers. API services may layer zod schemas * on top using the same shape definitions. */ import type { AnyBlock, BlockType } from "../types/content-blocks.js"; export type ValidationResult = { ok: true; data: D; } | { ok: false; error: string; }; export interface BlockPlugin { type: K; /** Current schema version. Bump when payload shape changes. */ version: number; /** Returns a fresh default payload (used by editor "insert block"). */ defaults: () => D; /** * Validates an unknown payload. Returns the typed payload on success, * or a human-readable error message on failure. */ validate: (data: unknown) => ValidationResult; /** * Declares nested block arrays owned by this block. The registry validates * those children recursively after this plugin's own payload validation. */ container?: { childArrays: (data: unknown) => { path: string; blocks: AnyBlock[]; }[]; /** Number of nested container levels allowed below the top level. */ maxDepth: number; }; /** * Optional migrator. Called when a stored block's `version` is lower than * the plugin's current `version`. Receives the old data and the version * it was stored at. Must return data conforming to the current version. */ migrate?: (oldData: unknown, fromVersion: number) => D; } export declare const v: { isObject(x: unknown): x is Record; isString(x: unknown): x is string; isNonEmptyString(x: unknown): x is string; isNumber(x: unknown): x is number; isBoolean(x: unknown): x is boolean; isArrayOfStrings(x: unknown): x is string[]; isOneOf(x: unknown, options: readonly T[]): x is T; }; /** * Result of parsing a stored blocks payload. * `errors` are non-fatal; problematic blocks are dropped from `blocks` * (or carried as `UnknownBlock` for forward-compat). Surface errors in admin * UI; never crash the renderer over them. */ export interface ParseResult { blocks: AnyBlock[]; errors: { index: number; type?: string; message: string; }[]; } export declare class BlockRegistry { private plugins; constructor(plugins?: BlockPlugin[]); /** Register or replace a plugin. Last writer wins (per type). */ register(plugin: BlockPlugin): void; get(type: string): BlockPlugin | undefined; has(type: string): boolean; types(): BlockType[]; /** * Validates a single block envelope. Migrates payload up to the plugin's * current version on the way through. Unknown types are passed through as * `UnknownBlock` so reads survive forward compatibility scenarios. */ validateBlock(raw: unknown): ValidationResult; private validateBlockAt; /** * Parse a stored blocks payload — accepts a JSON string, an array, or * null/undefined. Returns valid blocks plus per-index error report. * * Does not throw. Renderers should always be able to render whatever * comes back, including an empty array. */ parseBlocks(raw: string | unknown[] | null | undefined): ParseResult; /** * Strict variant of `parseBlocks`. Throws if any block fails validation. * Use on the write path where merchant input must be rejected on error. */ parseBlocksStrict(raw: string | unknown[] | null | undefined): AnyBlock[]; /** Serialize for storage. Round-trip safe. */ serialize(blocks: AnyBlock[]): string; } //# sourceMappingURL=registry.d.ts.map