import type { Component } from 'vue';
import type { Effect, Schema } from 'effect';
import type { Environment } from '../../../vendor/cel-js/lib/index.js';
type AnySchema = Schema.Schema<any, any, never>;
type SchemaFactory = (configure: (env: Environment) => void) => AnySchema;
/**
 * Capabilities a migration function may need from the host. Currently exposes
 * the Nuxt-provided CEL evaluator so legacy fields with embedded CEL
 * expressions can be evaluated during the rewrite. New capabilities are
 * additive — extend this type rather than introducing a parallel context.
 */
export type MigrationContext = Readonly<{
    $cel: <T>(expression: string, context?: Record<string, unknown>) => Effect.Effect<T, unknown>;
}>;
/**
 * Migrates a value of a source schema to this entry's schema. Lives on the
 * target (newer) entry. The Effect's success channel is the migrated value;
 * failures surface to the host as a toast — see
 * src/runtime/components/form/config.vue's migrate handler.
 *
 * The target is selected by one of two rules: (a) same `type` with a strictly
 * newer `compatibilityDate`, or (b) an explicit `migrateFrom` declaration on
 * the target naming this source `(type, compatibilityDate)`. Either way the
 * migrate function only sees the previous value and the host capabilities.
 */
export type MigrateFn = (prev: unknown, ctx: MigrationContext) => Effect.Effect<unknown, Error>;
/**
 * Identifies an entry by `(type, compatibilityDate)`. Used for `migrateFrom`
 * declarations on a target, and for the cross-type form of `supersededBy`
 * exposed on a deprecated entry.
 *
 * Migration declarations only ever live on the *new* (target) code — old
 * folders are never modified to announce that they have been superseded.
 */
export type MigrateSource = Readonly<{
    type: string;
    compatibilityDate: string;
}>;
export type FieldSizeRange = Readonly<{
    /** Span (in step units) used when the field is first placed. */
    initial: number;
    /** Lower bound (inclusive) the user may shrink the field to. */
    min: number;
    /** Upper bound (inclusive) the user may grow the field to. */
    max: number;
    /**
     * When true, this axis escapes the grid's `1fr` equal-share and follows
     * content instead. Currently honored only on `h` by the form runtime: any
     * row track containing at least one visible field whose `h.grow` is true is
     * rendered as `auto`, while other rows keep `minmax(0, 1fr)`.
     */
    grow?: boolean;
}>;
export type FieldMetadata = Readonly<{
    name: string;
    icon: string;
    w: FieldSizeRange;
    h: FieldSizeRange;
    /**
     * Whether this field can be configured *inline* — in a right-docked pane —
     * while the layout editor is in fullscreen. Absent / `true` → supported
     * (the default for simple fields). Set `false` for fields whose config is
     * too large or too structurally nested to fit a docked pane (list, table,
     * actions, collapsible); those keep the drill-down behavior, which exits
     * fullscreen. See `BlockLayoutEditor`'s inline-config pane.
     */
    inlineConfig?: boolean;
    /**
     * Whether this field is *selection-like* — it publishes its currently-resolved
     * full option to the `selections` registry at runtime (see
     * `utils/selections-registry`), keyed by its uuid. The form's unit-config reads
     * this to build the selection roster the ExpressionEditor advertises: a sibling
     * expression reaches the chosen record via `selections["<id>"].code`, and the
     * editor renders that uuid as this field's name. Set it together with the
     * runtime publish so the picker never advertises a field that writes nothing.
     */
    selection?: boolean;
}>;
/**
 * Optional creation-time defaults factory. Returns a partial config that
 * merges into the seed when the user adds a new field, so newly-added fields
 * arrive with sensible values populated. Schemas remain pure validators —
 * defaults live here. Mirrors `getColumnDefaults` in table/config.vue.
 */
export type FieldDefaults = () => Record<string, any>;
export type FieldEntry = Readonly<{
    type: string;
    compatibilityDate: string;
    metadata: FieldMetadata;
    schema: SchemaFactory;
    config: Component;
    runtime: Component;
    /**
     * True iff this entry is shadowed by either (a) a newer-date entry sharing
     * its `type`, or (b) another entry whose `migrateFrom` names this one.
     */
    deprecated: boolean;
    /**
     * Identifies the entry that supersedes this one. Same `type` for the
     * date-versioned rule; a different `type` for declared cross-type
     * migrations.
     */
    supersededBy?: MigrateSource;
    /**
     * Optional migration from a recognized source schema to this entry's
     * schema. When present, the host renders a "迁移" button on deprecated
     * entries whose target exposes this function.
     */
    migrate?: MigrateFn;
    /** Source schemas this entry accepts migration from. See module field. */
    migrateFrom?: ReadonlyArray<MigrateSource>;
    /**
     * Optional creation-time defaults. The host merges the returned partial
     * onto the seed when the user adds a new field via the picker. Absent →
     * the field is created with only `{ id, type, compatibilityDate }`.
     */
    defaults?: FieldDefaults;
}>;
export declare const FIELDS: ReadonlyArray<FieldEntry>;
export declare function allFieldSchemas(configure: (env: Environment) => void): ReadonlyArray<AnySchema>;
export declare function findField(type: string, compatibilityDate: string): FieldEntry | undefined;
/**
 * Finds the registry entry that has declared `(type, compatibilityDate)` as a
 * migration source on its `migrateFrom`. Use when a stored value's identity
 * no longer matches any registry entry (the old folder was renamed away) —
 * a present return means the value is still migratable via the target's
 * `migrate`.
 *
 * Note: for the date-versioned rule (same `type`, newer `compatibilityDate`)
 * the entry itself is in the registry and tagged `deprecated`/`supersededBy`;
 * callers reach the target through `findField(supersededBy.type, …)` rather
 * than this function.
 */
export declare function findMigrationTarget(type: string, compatibilityDate: string): FieldEntry | undefined;
export {};
