mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
feat(editor): Add connection port validation on new canvas (no-changelog) (#11342)
This commit is contained in:
parent
d04860d19e
commit
5fae187a0a
|
@ -1133,6 +1133,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [],
|
outputs: [],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
type: 'targetType',
|
type: 'targetType',
|
||||||
|
@ -1142,6 +1147,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: targetNode.type,
|
name: targetNode.type,
|
||||||
inputs: [],
|
inputs: [],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1155,14 +1165,7 @@ describe('useCanvasOperations', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isConnectionAllowed } = useCanvasOperations({ router });
|
const { isConnectionAllowed } = useCanvasOperations({ router });
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
),
|
|
||||||
).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if target node does not exist in the workflow', () => {
|
it('should return false if target node does not exist in the workflow', () => {
|
||||||
|
@ -1178,6 +1181,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [],
|
outputs: [],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
type: 'targetType',
|
type: 'targetType',
|
||||||
|
@ -1187,6 +1195,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: targetNode.type,
|
name: targetNode.type,
|
||||||
inputs: [NodeConnectionType.Main],
|
inputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1199,14 +1212,7 @@ describe('useCanvasOperations', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isConnectionAllowed } = useCanvasOperations({ router });
|
const { isConnectionAllowed } = useCanvasOperations({ router });
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
),
|
|
||||||
).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if source node does not have connection type', () => {
|
it('should return false if source node does not have connection type', () => {
|
||||||
|
@ -1221,6 +1227,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.AiTool,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
|
@ -1231,6 +1242,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: 'targetType',
|
name: 'targetType',
|
||||||
inputs: [NodeConnectionType.AiTool],
|
inputs: [NodeConnectionType.AiTool],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.AiTool,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1247,14 +1263,7 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.AiTool,
|
|
||||||
NodeConnectionType.AiTool,
|
|
||||||
),
|
|
||||||
).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if target node does not have connection type', () => {
|
it('should return false if target node does not have connection type', () => {
|
||||||
|
@ -1269,6 +1278,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
|
@ -1279,6 +1293,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: 'targetType',
|
name: 'targetType',
|
||||||
inputs: [NodeConnectionType.AiTool],
|
inputs: [NodeConnectionType.AiTool],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.AiTool,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1295,14 +1314,7 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.AiTool,
|
|
||||||
),
|
|
||||||
).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if source node type is not allowed by target node input filter', () => {
|
it('should return false if source node type is not allowed by target node input filter', () => {
|
||||||
|
@ -1318,6 +1330,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
|
@ -1336,6 +1353,11 @@ describe('useCanvasOperations', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1352,20 +1374,12 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
),
|
|
||||||
).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if all conditions including filter are met', () => {
|
it('should return false if source node type does not have connection type index', () => {
|
||||||
const workflowsStore = mockedStore(useWorkflowsStore);
|
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||||
const nodeTypesStore = mockedStore(useNodeTypesStore);
|
const nodeTypesStore = mockedStore(useNodeTypesStore);
|
||||||
|
|
||||||
const sourceNode = mockNode({
|
const sourceNode = mockNode({
|
||||||
id: '1',
|
id: '1',
|
||||||
type: 'sourceType',
|
type: 'sourceType',
|
||||||
|
@ -1376,6 +1390,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 1,
|
||||||
|
};
|
||||||
|
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
|
@ -1394,6 +1413,11 @@ describe('useCanvasOperations', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1410,14 +1434,128 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
isConnectionAllowed(
|
});
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
it('should return false if target node type does not have connection type index', () => {
|
||||||
NodeConnectionType.Main,
|
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||||
NodeConnectionType.Main,
|
const nodeTypesStore = mockedStore(useNodeTypesStore);
|
||||||
),
|
const sourceNode = mockNode({
|
||||||
).toBe(true);
|
id: '1',
|
||||||
|
type: 'sourceType',
|
||||||
|
name: 'Source Node',
|
||||||
|
typeVersion: 1,
|
||||||
|
});
|
||||||
|
const sourceNodeTypeDescription = mockNodeTypeDescription({
|
||||||
|
name: sourceNode.type,
|
||||||
|
outputs: [NodeConnectionType.Main],
|
||||||
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const targetNode = mockNode({
|
||||||
|
id: '2',
|
||||||
|
type: 'targetType',
|
||||||
|
name: 'Target Node',
|
||||||
|
typeVersion: 1,
|
||||||
|
});
|
||||||
|
const targetNodeTypeDescription = mockNodeTypeDescription({
|
||||||
|
name: targetNode.type,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
filter: {
|
||||||
|
nodes: [sourceNode.type],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
|
||||||
|
const { isConnectionAllowed, editableWorkflowObject } = useCanvasOperations({ router });
|
||||||
|
|
||||||
|
editableWorkflowObject.value.nodes[sourceNode.name] = sourceNode;
|
||||||
|
editableWorkflowObject.value.nodes[targetNode.name] = targetNode;
|
||||||
|
nodeTypesStore.getNodeType = vi.fn(
|
||||||
|
(nodeTypeName: string) =>
|
||||||
|
({
|
||||||
|
[sourceNode.type]: sourceNodeTypeDescription,
|
||||||
|
[targetNode.type]: targetNodeTypeDescription,
|
||||||
|
})[nodeTypeName],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if all conditions including filter are met', () => {
|
||||||
|
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||||
|
const nodeTypesStore = mockedStore(useNodeTypesStore);
|
||||||
|
|
||||||
|
const sourceNode = mockNode({
|
||||||
|
id: '1',
|
||||||
|
type: 'sourceType',
|
||||||
|
name: 'Source Node',
|
||||||
|
typeVersion: 1,
|
||||||
|
});
|
||||||
|
const sourceNodeTypeDescription = mockNodeTypeDescription({
|
||||||
|
name: sourceNode.type,
|
||||||
|
outputs: [NodeConnectionType.Main],
|
||||||
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const targetNode = mockNode({
|
||||||
|
id: '2',
|
||||||
|
type: 'targetType',
|
||||||
|
name: 'Target Node',
|
||||||
|
typeVersion: 1,
|
||||||
|
});
|
||||||
|
const targetNodeTypeDescription = mockNodeTypeDescription({
|
||||||
|
name: targetNode.type,
|
||||||
|
inputs: [
|
||||||
|
{
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
filter: {
|
||||||
|
nodes: [sourceNode.type],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
|
||||||
|
const { isConnectionAllowed, editableWorkflowObject } = useCanvasOperations({ router });
|
||||||
|
|
||||||
|
editableWorkflowObject.value.nodes[sourceNode.name] = sourceNode;
|
||||||
|
editableWorkflowObject.value.nodes[targetNode.name] = targetNode;
|
||||||
|
nodeTypesStore.getNodeType = vi.fn(
|
||||||
|
(nodeTypeName: string) =>
|
||||||
|
({
|
||||||
|
[sourceNode.type]: sourceNodeTypeDescription,
|
||||||
|
[targetNode.type]: targetNodeTypeDescription,
|
||||||
|
})[nodeTypeName],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if all conditions are met and no filter is set', () => {
|
it('should return true if all conditions are met and no filter is set', () => {
|
||||||
|
@ -1434,6 +1572,11 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const targetNode = mockNode({
|
const targetNode = mockNode({
|
||||||
id: '2',
|
id: '2',
|
||||||
|
@ -1449,6 +1592,11 @@ describe('useCanvasOperations', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: targetNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1465,14 +1613,7 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, targetNode, sourceHandle, targetHandle)).toBe(true);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
),
|
|
||||||
).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if node connecting to itself', () => {
|
it('should return true if node connecting to itself', () => {
|
||||||
|
@ -1489,6 +1630,16 @@ describe('useCanvasOperations', () => {
|
||||||
name: sourceNode.type,
|
name: sourceNode.type,
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
});
|
});
|
||||||
|
const sourceHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
const targetHandle: IConnection = {
|
||||||
|
node: sourceNode.name,
|
||||||
|
type: NodeConnectionType.Main,
|
||||||
|
index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
const workflowObject = createTestWorkflowObject(workflowsStore.workflow);
|
||||||
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
|
||||||
|
@ -1503,14 +1654,7 @@ describe('useCanvasOperations', () => {
|
||||||
})[nodeTypeName],
|
})[nodeTypeName],
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(isConnectionAllowed(sourceNode, sourceNode, sourceHandle, targetHandle)).toBe(true);
|
||||||
isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
sourceNode,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
NodeConnectionType.Main,
|
|
||||||
),
|
|
||||||
).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1154,14 +1154,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
||||||
connection,
|
connection,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (!isConnectionAllowed(sourceNode, targetNode, mappedConnection[0], mappedConnection[1])) {
|
||||||
!isConnectionAllowed(
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
mappedConnection[0].type,
|
|
||||||
mappedConnection[1].type,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1298,12 +1291,12 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
||||||
function isConnectionAllowed(
|
function isConnectionAllowed(
|
||||||
sourceNode: INodeUi,
|
sourceNode: INodeUi,
|
||||||
targetNode: INodeUi,
|
targetNode: INodeUi,
|
||||||
sourceConnectionType: NodeConnectionType,
|
sourceConnection: IConnection,
|
||||||
targetConnectionType: NodeConnectionType,
|
targetConnection: IConnection,
|
||||||
): boolean {
|
): boolean {
|
||||||
const blocklist = [STICKY_NODE_TYPE];
|
const blocklist = [STICKY_NODE_TYPE];
|
||||||
|
|
||||||
if (sourceConnectionType !== targetConnectionType) {
|
if (sourceConnection.type !== targetConnection.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1329,10 +1322,13 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
||||||
|
|
||||||
const sourceNodeHasOutputConnectionOfType = !!sourceNodeOutputs.find((output) => {
|
const sourceNodeHasOutputConnectionOfType = !!sourceNodeOutputs.find((output) => {
|
||||||
const outputType = typeof output === 'string' ? output : output.type;
|
const outputType = typeof output === 'string' ? output : output.type;
|
||||||
return outputType === sourceConnectionType;
|
return outputType === sourceConnection.type;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!sourceNodeHasOutputConnectionOfType) {
|
const sourceNodeHasOutputConnectionPortOfType =
|
||||||
|
sourceConnection.index < sourceNodeOutputs.length;
|
||||||
|
|
||||||
|
if (!sourceNodeHasOutputConnectionOfType || !sourceNodeHasOutputConnectionPortOfType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,7 +1350,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
||||||
|
|
||||||
const targetNodeHasInputConnectionOfType = !!targetNodeInputs.find((input) => {
|
const targetNodeHasInputConnectionOfType = !!targetNodeInputs.find((input) => {
|
||||||
const inputType = typeof input === 'string' ? input : input.type;
|
const inputType = typeof input === 'string' ? input : input.type;
|
||||||
if (inputType !== targetConnectionType) return false;
|
if (inputType !== targetConnection.type) return false;
|
||||||
|
|
||||||
const filter = typeof input === 'object' && 'filter' in input ? input.filter : undefined;
|
const filter = typeof input === 'object' && 'filter' in input ? input.filter : undefined;
|
||||||
if (filter?.nodes.length && !filter.nodes.includes(sourceNode.type)) {
|
if (filter?.nodes.length && !filter.nodes.includes(sourceNode.type)) {
|
||||||
|
@ -1373,7 +1369,9 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
return targetNodeHasInputConnectionOfType;
|
const targetNodeHasInputConnectionPortOfType = targetConnection.index < targetNodeInputs.length;
|
||||||
|
|
||||||
|
return targetNodeHasInputConnectionOfType && targetNodeHasInputConnectionPortOfType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addConnections(
|
function addConnections(
|
||||||
|
|
Loading…
Reference in a new issue