import type { ConnectionType } from "..";
import type { Connection, ConnectionByType, ConnectionKindType, Resource, ResourceId, ResourceType } from "../../Blueprint";
import type { Maybe } from "../../Common";
export declare type ConnectionProducer<TKind extends Connection = Connection> = (source: ResourceId, target: ResourceId, kind: TKind) => Connection;
export declare type CompositeKey = string;
export declare type AllowedConnectionsMapping = {
    [K in ResourceType]?: TargetConnectionsMapping;
};
export declare type TargetConnectionsMapping = {
    [K in ResourceType]?: ConnectionType;
};
export declare type ConnectionMappingRootKeys = 'source' | 'target';
export declare function mkCompositeKey(source: ResourceType, target: ResourceType, kind: ConnectionKindType): CompositeKey;
export declare class ConnectionsFactory {
    private readonly registry;
    constructor(connectionDefinitions?: (factory: ConnectionsFactory) => void);
    buildConnection(source: Resource, target: Resource, connectionKind: Connection): Maybe<Connection>;
    isConnectionValid(sourceType: ResourceType, targetType: ResourceType, connectionType: ConnectionType): boolean;
    /**
     * Registers a new Connection Producer.
     *
     * Prefer using one of the other more specialized methods.
     */
    registerConnectionProducer<TKind extends ConnectionKindType = ConnectionKindType>(sourceType: ResourceType, targetType: ResourceType, kind: TKind, producer: ConnectionProducer<ConnectionByType[TKind]>): void;
    /**
     * Registers the connection type with the specified resource types
     * @param type The connection's type of the connection to register
     * @param edges Connection edges, of an array of connection edges
     */
    registerConnection(type: ConnectionType, edges: ConnectionEdges | [ConnectionEdges, ...ConnectionEdges[]]): void;
    /**
     * Creates an allowed connections mapping
     * @param rootKeyType Defines what the keys on the returned object represent. \
     * If `'source'`, then the result object is a mapping from *source* resource-type,
     * to a mapping from *target* resource type to an allowed connection. \
     * \
     * If `'target'`, then the result object is a mapping from *target* resource-type,
     * to a mapping from *source* resource type to an allowed connection
     * @returns An allowed connections mapping
     */
    allowedConnectionsMapping(rootKeyType: ConnectionMappingRootKeys): AllowedConnectionsMapping;
}
/**
 * Specifies connection edges as the cartesian product of sources and targets
 *
 * @example
 * const edges: ConnectionEdges = {
 * 	sources: ['a', 'b'],
 * 	targets: ['x', 'y', 'z']
 * }
 *
 * // Will defined the following connection edges:
 * // 'a' → 'x'
 * // 'a' → 'y'
 * // 'a' → 'z'
 * // 'b' → 'x'
 * // 'b' → 'y'
 * // 'b' → 'z'
 * */
export interface ConnectionEdges {
    /** The connection sources */
    sources: [ResourceType, ...ResourceType[]];
    /** The connection targets */
    targets: [ResourceType, ...ResourceType[]];
}
