77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
import type { Connection, Edge as RFEdge, Node as RFNode } from "@xyflow/react";
|
|
|
|
import {
|
|
validateCanvasConnectionPolicy,
|
|
type CanvasConnectionValidationReason,
|
|
} from "@/lib/canvas-connection-policy";
|
|
|
|
export function validateCanvasConnection(
|
|
connection: Connection,
|
|
nodes: RFNode[],
|
|
edges: RFEdge[],
|
|
edgeToReplaceId?: string,
|
|
): CanvasConnectionValidationReason | null {
|
|
if (!connection.source || !connection.target) return "incomplete";
|
|
if (connection.source === connection.target) return "self-loop";
|
|
|
|
const sourceNode = nodes.find((node) => node.id === connection.source);
|
|
const targetNode = nodes.find((node) => node.id === connection.target);
|
|
if (!sourceNode || !targetNode) return "unknown-node";
|
|
|
|
return validateCanvasConnectionByType({
|
|
sourceType: sourceNode.type ?? "",
|
|
targetType: targetNode.type ?? "",
|
|
targetNodeId: connection.target,
|
|
edges,
|
|
edgeToReplaceId,
|
|
});
|
|
}
|
|
|
|
export function validateCanvasConnectionByType(args: {
|
|
sourceType: string;
|
|
targetType: string;
|
|
targetNodeId: string;
|
|
edges: RFEdge[];
|
|
edgeToReplaceId?: string;
|
|
}): CanvasConnectionValidationReason | null {
|
|
const targetIncomingCount = args.edges.filter(
|
|
(edge) => edge.target === args.targetNodeId && edge.id !== args.edgeToReplaceId,
|
|
).length;
|
|
|
|
return validateCanvasConnectionPolicy({
|
|
sourceType: args.sourceType,
|
|
targetType: args.targetType,
|
|
targetIncomingCount,
|
|
});
|
|
}
|
|
|
|
export function validateCanvasEdgeSplit(args: {
|
|
nodes: RFNode[];
|
|
edges: RFEdge[];
|
|
splitEdge: RFEdge;
|
|
middleNode: RFNode;
|
|
}): CanvasConnectionValidationReason | null {
|
|
const sourceNode = args.nodes.find((node) => node.id === args.splitEdge.source);
|
|
const targetNode = args.nodes.find((node) => node.id === args.splitEdge.target);
|
|
|
|
if (!sourceNode || !targetNode) {
|
|
return "unknown-node";
|
|
}
|
|
|
|
return (
|
|
validateCanvasConnectionByType({
|
|
sourceType: sourceNode.type ?? "",
|
|
targetType: args.middleNode.type ?? "",
|
|
targetNodeId: args.middleNode.id,
|
|
edges: args.edges,
|
|
}) ??
|
|
validateCanvasConnectionByType({
|
|
sourceType: args.middleNode.type ?? "",
|
|
targetType: targetNode.type ?? "",
|
|
targetNodeId: targetNode.id,
|
|
edges: args.edges,
|
|
edgeToReplaceId: args.splitEdge.id,
|
|
})
|
|
);
|
|
}
|