import { type Static, type TSchema } from "../../core/utils";
import type { HTMLInputTypeAttribute, InputHTMLAttributes } from "react";
import type { EntityManager } from "../entities";
import type { FieldSpec } from "../../data/connection/Connection";
import * as tbbox from "@sinclair/typebox";
import type { TFieldTSType } from "../../data/entities/EntityTypescript";
export declare const ActionContext: readonly ["create", "read", "update", "delete"];
export type TActionContext = (typeof ActionContext)[number];
export declare const RenderContext: readonly ["form", "table", "read", "submit"];
export type TRenderContext = (typeof RenderContext)[number];
declare const TmpContext: readonly ["create", "read", "update", "delete", "form", "table", "submit"];
export type TmpActionAndRenderContext = (typeof TmpContext)[number];
export declare const baseFieldConfigSchema: tbbox.TObject<{
    label: tbbox.TOptional<tbbox.TString>;
    description: tbbox.TOptional<tbbox.TString>;
    required: tbbox.TOptional<tbbox.TBoolean>;
    fillable: tbbox.TOptional<tbbox.TUnion<[tbbox.TBoolean, tbbox.TArray<tbbox.TUnsafe<"create" | "read" | "update" | "delete">>]>>;
    hidden: tbbox.TOptional<tbbox.TUnion<[tbbox.TBoolean, tbbox.TArray<tbbox.TUnsafe<"form" | "table" | "create" | "read" | "update" | "delete" | "submit">>]>>;
    virtual: tbbox.TOptional<tbbox.TBoolean>;
    default_value: tbbox.TOptional<tbbox.TAny>;
}>;
export type BaseFieldConfig = Static<typeof baseFieldConfigSchema>;
export declare abstract class Field<Config extends BaseFieldConfig = BaseFieldConfig, Type = any, Required extends true | false = false> {
    _required: Required;
    _type: Type;
    /**
     * Property name that gets persisted on database
     */
    readonly name: string;
    readonly type: string;
    readonly config: Config;
    constructor(name: string, config?: Partial<Config>);
    getType(): string;
    protected abstract getSchema(): TSchema;
    /**
     * Used in SchemaManager.ts
     * @param em
     */
    schema(): FieldSpec | undefined;
    hasDefault(): boolean;
    getDefault(): any;
    isFillable(context?: TActionContext): boolean;
    isHidden(context?: TmpActionAndRenderContext): boolean;
    isRequired(): boolean;
    /**
     * Virtual fields are not persisted or retrieved from database
     * Used for MediaField, to add specifics about uploads, etc.
     */
    isVirtual(): boolean;
    getLabel(options?: {
        fallback?: boolean;
    }): string | undefined;
    getDescription(): string | undefined;
    /**
     * [GET] DB -> field.transformRetrieve -> [sent]
     *   table: form.getValue("table")
     *   form: form.getValue("form") -> modified -> form.getValue("submit") -> [sent]
     *
     * [PATCH] body parse json -> field.transformPersist -> [stored]
     *
     * @param value
     * @param context
     */
    getValue(value: any, context?: TRenderContext): any;
    getHtmlConfig(): {
        element: HTMLInputTypeAttribute | string;
        props?: InputHTMLAttributes<any>;
    };
    isValid(value: any, context: TActionContext): boolean;
    /**
     * Transform value after retrieving from database
     * @param value
     */
    transformRetrieve(value: any): any;
    /**
     * Transform value before persisting to database
     * @param value
     * @param em EntityManager (optional, for relation fields)
     */
    transformPersist(value: unknown, em: EntityManager<any>, context: TActionContext): Promise<any>;
    protected toSchemaWrapIfRequired<Schema extends TSchema>(schema: Schema): Schema | (Schema extends tbbox.TOptional<infer S extends TSchema> ? tbbox.TOptional<S> : tbbox.Ensure<tbbox.TOptional<Schema>>);
    protected nullish(value: any): boolean;
    toJsonSchema(): TSchema;
    toType(): TFieldTSType;
    toJSON(): {
        type: any;
        config: Config;
    };
}
export {};
