/** * Connection validation utilities for FlowDrop */ import type { NodeMetadata, NodePort, NodeDataType, WorkflowNode, WorkflowEdge, PortConfig, PortDataTypeConfig } from '../types/index.js'; /** * Determines if an edge is a loopback edge. * Loopback edges target the special `loop_back` input port on ForEach nodes. * These edges are used to trigger the next iteration in a loop construct. * * @param edge - The edge to check * @returns True if the edge is a loopback edge * * @example * ```typescript * const edge = { targetHandle: "foreach.1-input-loop_back", ... }; * const isLoop = isLoopbackEdge(edge); // true * ``` */ export declare function isLoopbackEdge(edge: WorkflowEdge): boolean; /** * Checks if a cycle consists entirely of loopback edges. * A valid loopback cycle only contains edges that target loop_back ports. * * @param cycleEdges - Array of edges that form a cycle * @returns True if all edges in the cycle are loopback edges */ export declare function isValidLoopbackCycle(cycleEdges: WorkflowEdge[]): boolean; /** * Configurable port compatibility checker */ export declare class PortCompatibilityChecker { private portConfig; private compatibilityMap; constructor(portConfig: PortConfig); /** * Build the compatibility map from configuration rules */ private buildCompatibilityMap; /** * Check if two data types are compatible for connection */ areDataTypesCompatible(outputType: NodeDataType, inputType: NodeDataType): boolean; /** * Get all compatible target types for a source type */ getCompatibleTypes(sourceType: NodeDataType): NodeDataType[]; /** * Get data type configuration by ID */ getDataTypeConfig(dataTypeId: string): PortDataTypeConfig | undefined; /** * Get all enabled data types */ getEnabledDataTypes(): PortDataTypeConfig[]; } /** * Initialize the global port compatibility checker */ export declare function initializePortCompatibility(portConfig: PortConfig): void; /** * Returns true if the port compatibility checker has been initialized. */ export declare function isPortCompatibilityInitialized(): boolean; /** * Get the global port compatibility checker */ export declare function getPortCompatibilityChecker(): PortCompatibilityChecker; /** * Get all possible connections from a source node to target nodes */ export declare function getPossibleConnections(sourceNode: WorkflowNode, targetNodes: WorkflowNode[], nodeTypes: NodeMetadata[]): Array<{ sourceNodeId: string; sourcePortId: string; sourcePort: NodePort; targetNodeId: string; targetPortId: string; targetPort: NodePort; compatible: boolean; }>; /** * Validate if a specific connection is valid */ export declare function validateConnection(sourceNodeId: string, sourcePortId: string, targetNodeId: string, targetPortId: string, nodes: WorkflowNode[], nodeTypes: NodeMetadata[]): { valid: boolean; error?: string; }; /** * Get connection suggestions for a node */ export declare function getConnectionSuggestions(nodeId: string, nodes: WorkflowNode[], nodeTypes: NodeMetadata[]): Array<{ nodeId: string; nodeName: string; portId: string; portName: string; portType: 'input' | 'output'; dataType: NodeDataType; compatible: boolean; }>; /** * Check if a workflow has any cycles (prevent infinite loops) * Note: This function detects ALL cycles, including valid loopback cycles. * Use `hasInvalidCycles` to check only for cycles that could cause infinite execution. * * @param nodes - Array of workflow nodes * @param edges - Array of workflow edges * @returns True if any cycle exists in the workflow */ export declare function hasCycles(nodes: WorkflowNode[], edges: WorkflowEdge[]): boolean; /** * Check if a workflow has any invalid cycles (non-loopback cycles). * This excludes valid loopback cycles used for ForEach iteration. * Only cycles that could cause infinite execution are detected. * * @param nodes - Array of workflow nodes * @param edges - Array of workflow edges * @returns True if any invalid (non-loopback) cycle exists * * @example * ```typescript * // A cycle through a loopback edge is valid (returns false) * // A cycle through regular data edges is invalid (returns true) * const hasInvalid = hasInvalidCycles(nodes, edges); * ``` */ export declare function hasInvalidCycles(nodes: WorkflowNode[], edges: WorkflowEdge[]): boolean; /** * Get the execution order for a workflow (topological sort) */ export declare function getExecutionOrder(nodes: WorkflowNode[], edges: WorkflowEdge[]): string[];