import type { BindingDiagnostic, BindingNodeContext, BindingValidationResult, DataBinding, DataBindingDocument, DataCatalog, DataCatalogIdentity, DataCondition, DataField, RepeatBinding } from './contracts.js'; /** A small expression language issued by a host source adapter, never by sampled data. */ export type BindingSourceExpression = { kind: 'identifier'; name: string; } | { kind: 'member'; object: BindingSourceExpression; property: string; optional?: boolean; } | { kind: 'call'; helper: string; arguments: readonly BindingSourceExpression[]; } | { kind: 'literal'; value: string | number | boolean | null; } | { kind: 'condition'; value: BindingSourceExpression; condition: DataCondition; } | { kind: 'text'; value: BindingSourceExpression; } | { kind: 'when-present'; value: BindingSourceExpression; present: BindingSourceExpression; missing: BindingSourceExpression; } | { kind: 'coalesce'; value: BindingSourceExpression; fallback: BindingSourceExpression; }; export interface BindingSourceProof { file: string; sourceRevision: string; /** SHA-256 of the complete original UTF-8 source file. */ fileHash: string; start: number; end: number; /** Original expression at this exact range. Not a fixture value. */ expected: string; } export interface BindingSourceResolution { sourceRef: string; expression: BindingSourceExpression; proof: BindingSourceProof; /** Identifiers proven to be in lexical scope by the host source adapter. */ identifiers: readonly string[]; /** Existing callable symbols explicitly approved by the host. No new hooks or imports are guessed. */ helpers: readonly string[]; /** A source adapter must explicitly acknowledge the presentation contract it emits. */ presentation: { missing: DataBinding['missing']; formatter?: DataBinding['formatter']; condition?: DataCondition; }; /** Host-declared render input override, scoped to one existing map callback. */ itemOverride?: { repeatId: string; itemIdentifier: string; property: string; }; } export interface RepeatSourceResolution { sourceRef: string; expression: BindingSourceExpression; proof: BindingSourceProof; identifiers: readonly string[]; helpers: readonly string[]; itemIdentifier: string; keyExpression: BindingSourceExpression; } export interface BindingSourceAdapter { id: string; version: string; resolveBinding(context: { catalog: DataCatalog; document: DataBindingDocument; binding: DataBinding; field: DataField; }): BindingSourceResolution | { unavailable: string; }; resolveRepeat?(context: { catalog: DataCatalog; document: DataBindingDocument; repeat: RepeatBinding; field: DataField; }): RepeatSourceResolution | { unavailable: string; }; } export interface BindingSourcePlan { schema: 'pygmalion.binding-source-plan'; version: 1; catalog: DataCatalogIdentity; adapter: { id: string; version: string; }; documentFingerprint: string; bindings: readonly { bindingId: string; nodeId: string; slotId: string; resolution: BindingSourceResolution; }[]; repeats: readonly { repeatId: string; templateNodeId: string; resolution: RepeatSourceResolution; }[]; /** Explicit source-owned disconnect policies. These never come from fixture values. */ replacements?: readonly { replacementId: string; nodeId: string; resolution: BindingSourceReplacement; }[]; } export interface BindingSourceReplacement { proof: BindingSourceProof; expression: BindingSourceExpression; identifiers: readonly string[]; helpers: readonly string[]; /** Replacing a collection still preserves its existing callback and stable key. */ repeat?: { itemIdentifier: string; keyExpression: BindingSourceExpression; }; } export declare function validateBindingSourceExpression(input: unknown, identifiers: readonly string[], helpers: readonly string[], options?: { allowLiteralRoot?: boolean; }): boolean; export declare function printBindingSourceExpression(expression: BindingSourceExpression): string; export declare function bindingDocumentFingerprint(document: DataBindingDocument): string; export declare function validBindingSourceProof(input: unknown, sourceRevision: string): input is BindingSourceProof; export declare function validateBindingSourcePlan(input: unknown): BindingValidationResult; /** Compile a reviewed-source proposal. This never mutates source and never emits literal-prop operations. */ export declare function compileBindingSourcePlan(catalog: DataCatalog, document: DataBindingDocument, nodes: readonly BindingNodeContext[], adapter?: BindingSourceAdapter): { status: 'ready' | 'blocked'; diagnostics: readonly BindingDiagnostic[]; plan?: BindingSourcePlan; };