MCPcopy Create free account
hub / github.com/ShipSecAI/studio / validateConnection

Function validateConnection

frontend/src/utils/connectionValidation.ts:18–171  ·  view source on GitHub ↗
(
  connection: Connection,
  nodes: Node<FrontendNodeData>[],
  edges: Edge[],
  getComponent: (slug: string) => ComponentMetadata | null,
)

Source from the content-addressed store, hash-verified

16}
17
18export function validateConnection(
19 connection: Connection,
20 nodes: Node<FrontendNodeData>[],
21 edges: Edge[],
22 getComponent: (slug: string) => ComponentMetadata | null,
23): ValidationResult {
24 const { source, target, sourceHandle, targetHandle } = connection;
25
26 // Basic validation
27 if (!source || !target) {
28 return { isValid: false, error: 'Invalid connection' };
29 }
30
31 if (source === target) {
32 return { isValid: false, error: 'Cannot connect node to itself' };
33 }
34
35 // Get source and target nodes
36 const sourceNode = nodes.find((node) => node.id === source);
37 const targetNode = nodes.find((node) => node.id === target);
38
39 if (!sourceNode || !targetNode) {
40 return { isValid: false, error: 'Source or target node not found' };
41 }
42
43 const sourceComponentSlug = sourceNode.data.componentId ?? sourceNode.data.componentSlug;
44 if (!sourceComponentSlug) {
45 return { isValid: false, error: 'Source component not found' };
46 }
47 const targetComponentSlug = targetNode.data.componentId ?? targetNode.data.componentSlug;
48 if (!targetComponentSlug) {
49 return { isValid: false, error: 'Target component not found' };
50 }
51
52 // Get component metadata
53 const sourceComponent = getComponent(sourceComponentSlug);
54 const targetComponent = getComponent(targetComponentSlug);
55
56 if (!sourceComponent || !targetComponent) {
57 return { isValid: false, error: 'Component metadata not found' };
58 }
59
60 // Validate handles exist
61 if (!sourceHandle || !targetHandle) {
62 return { isValid: false, error: 'Connection handles not specified' };
63 }
64
65 // Get port metadata (with support for dynamic outputs/inputs)
66 // 1. DYNAMIC OUTPUTS from source
67 let sourceOutputs = (sourceNode.data as any).dynamicOutputs || sourceComponent.outputs || [];
68
69 // Special case: Tool Mode virtual port
70 const sourceConfig = sourceNode.data.config as any;
71 if (sourceConfig?.isToolMode || sourceConfig?.mode === 'tool') {
72 sourceOutputs = [
73 ...sourceOutputs,
74 {
75 id: 'tools',

Callers 1

CanvasFunction · 0.90

Calls 8

resolvePortTypeFunction · 0.90
arePortTypesCompatibleFunction · 0.90
describePortTypeFunction · 0.90
getComponentFunction · 0.85
wouldCreateCycleFunction · 0.85
parseMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected