import { type Static } from "../../core/utils";
import type { ExpressionBuilder, SelectQueryBuilder } from "kysely";
import type { Entity, EntityData, EntityManager } from "../entities";
import { type EntityRelationAnchor, type MutationInstructionResponse, RelationHelper } from "../relations";
import type { RepoQuery } from "../server/query";
import type { RelationType } from "./relation-types";
import * as tbbox from "@sinclair/typebox";
import type { PrimaryFieldType } from "../../core";
declare const directions: readonly ["source", "target"];
export type TDirection = (typeof directions)[number];
export type KyselyJsonFrom = any;
export type KyselyQueryBuilder = SelectQueryBuilder<any, any, any>;
export type BaseRelationConfig = Static<typeof EntityRelation.schema>;
export declare abstract class EntityRelation<Schema extends typeof EntityRelation.schema = typeof EntityRelation.schema> {
    config: Static<Schema>;
    source: EntityRelationAnchor;
    target: EntityRelationAnchor;
    directions: TDirection[];
    static schema: tbbox.TObject<{
        mappedBy: tbbox.TOptional<tbbox.TString>;
        inversedBy: tbbox.TOptional<tbbox.TString>;
        required: tbbox.TOptional<tbbox.TBoolean>;
    }>;
    constructor(source: EntityRelationAnchor, target: EntityRelationAnchor, config?: Partial<Static<Schema>>);
    abstract initialize(em: EntityManager<any>): void;
    /**
     * Build the "with" part of the query.
     *
     * @param entity requesting entity, so target needs to be added
     * @param qb
     * @param jsonFrom
     */
    abstract buildWith(entity: Entity, reference: string): (eb: ExpressionBuilder<any, any>) => KyselyQueryBuilder;
    abstract buildJoin(entity: Entity, qb: KyselyQueryBuilder, reference: string): KyselyQueryBuilder;
    getReferenceQuery(entity: Entity, id: PrimaryFieldType, reference: string): Partial<RepoQuery>;
    /** @deprecated */
    helper(entity_name: string): RelationHelper;
    /**
     * Get the other side of the relation quickly
     * @param entity
     */
    other(entity: Entity | string): EntityRelationAnchor;
    self(entity: Entity | string): EntityRelationAnchor;
    ref(reference: string): EntityRelationAnchor;
    otherRef(reference: string): EntityRelationAnchor;
    visibleFrom(from: "source" | "target"): boolean;
    /**
     * Hydrate the relation. "entity" represents where the payload belongs to.
     * E.g. if entity is "categories", then value is the result of categories
     *
     * IMPORTANT: This method is called from EM, high potential of recursion!
     *
     * @param entity
     * @param value
     * @param em
     */
    hydrate(entity: Entity | string, value: EntityData[], em: EntityManager<any>): EntityData | EntityData[] | undefined;
    /**
     * Determines if the relation is listable for the given entity
     * If the given entity is the one with the local reference, then it's not listable
     * Only if there are multiple, which is generally the other side (except for 1:1)
     * @param entity
     */
    isListableFor(entity: Entity): boolean;
    abstract type(): RelationType;
    get required(): boolean;
    $set(em: EntityManager<any>, key: string, value: unknown): Promise<void | MutationInstructionResponse>;
    $create(em: EntityManager<any>, key: string, value: unknown): Promise<void | MutationInstructionResponse>;
    $attach(em: EntityManager<any>, key: string, value: unknown): Promise<void | MutationInstructionResponse>;
    $detach(em: EntityManager<any>, key: string, value: unknown): Promise<void | MutationInstructionResponse>;
    getName(): string;
    toJSON(): {
        type: RelationType;
        source: string;
        target: string;
        config: (Schema & {
            params: [];
        })["static"];
    };
}
export {};
