feat(editor): Add support for connection validation (no-changelog) (#10059)

This commit is contained in:
Alex Grozav
2024-07-15 18:32:02 +03:00
committed by GitHub
parent 0d12f0a6b3
commit bb354f3c88
4 changed files with 155 additions and 30 deletions

View File

@@ -2,6 +2,8 @@ import { ref } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import { useNodeConnections } from '@/composables/useNodeConnections';
import type { CanvasNodeData } from '@/types';
import { CanvasConnectionMode } from '@/types';
import { createCanvasConnectionHandleString } from '@/utils/canvasUtilsV2';
describe('useNodeConnections', () => {
const defaultConnections = { input: {}, output: {} };
@@ -158,4 +160,87 @@ describe('useNodeConnections', () => {
);
});
});
describe('isValidConnection', () => {
const inputs = ref<CanvasNodeData['inputs']>([]);
const outputs = ref<CanvasNodeData['outputs']>([]);
const { isValidConnection } = useNodeConnections({
inputs,
outputs,
connections: defaultConnections,
});
it('returns false if source and target nodes are the same', () => {
const connection = {
source: 'node1',
target: 'node1',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
index: 0,
}),
};
expect(isValidConnection(connection)).toBe(false);
});
it('returns false if source and target handles are of the same mode', () => {
const connection = {
source: 'node1',
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
index: 0,
}),
};
expect(isValidConnection(connection)).toBe(false);
});
it('returns false if source and target handles are of different types', () => {
const connection = {
source: 'node1',
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.AiMemory,
index: 0,
}),
};
expect(isValidConnection(connection)).toBe(false);
});
it('returns true if source and target nodes are different, modes are different, and types are the same', () => {
const connection = {
source: 'node1',
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
index: 0,
}),
};
expect(isValidConnection(connection)).toBe(true);
});
});
});

View File

@@ -2,6 +2,8 @@ import type { CanvasNodeData } from '@/types';
import type { MaybeRef } from 'vue';
import { computed, unref } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import type { Connection } from '@vue-flow/core';
import { parseCanvasConnectionHandleString } from '@/utils/canvasUtilsV2';
export function useNodeConnections({
inputs,
@@ -48,6 +50,25 @@ export function useNodeConnections({
() => unref(connections).output[NodeConnectionType.Main] ?? [],
);
/**
* Connection validation
*/
function isValidConnection(connection: Connection) {
const { type: sourceType, mode: sourceMode } = parseCanvasConnectionHandleString(
connection.sourceHandle,
);
const { type: targetType, mode: targetMode } = parseCanvasConnectionHandleString(
connection.targetHandle,
);
const isSameNode = connection.source === connection.target;
const isSameMode = sourceMode === targetMode;
const isSameType = sourceType === targetType;
return !isSameNode && !isSameMode && isSameType;
}
return {
mainInputs,
nonMainInputs,
@@ -56,5 +77,6 @@ export function useNodeConnections({
mainOutputs,
nonMainOutputs,
mainOutputConnections,
isValidConnection,
};
}