refactor: Migrate NodeConnectionType to const object type (no-changelog) (#14078)

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Alex Grozav
2025-03-21 14:01:26 +02:00
committed by GitHub
parent 7e8179b848
commit 8215e0b59f
703 changed files with 3104 additions and 3018 deletions

View File

@@ -11,7 +11,8 @@ import type {
ExecutionOutputMapData,
} from '@/types';
import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';
import { NodeConnectionType } from 'n8n-workflow';
import type { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { GraphEdge, GraphNode, ViewportTransform } from '@vue-flow/core';
import type { EventBus } from '@n8n/utils/event-bus';
import { createEventBus } from '@n8n/utils/event-bus';
@@ -172,7 +173,7 @@ export function createCanvasNodeProvide({
export function createCanvasHandleProvide({
label = 'Handle',
mode = CanvasConnectionMode.Input,
type = NodeConnectionType.Main,
type = NodeConnectionTypes.Main,
index = 0,
runData,
isConnected = false,
@@ -190,7 +191,9 @@ export function createCanvasHandleProvide({
isReadOnly?: boolean;
isRequired?: boolean;
} = {}) {
const maxConnections = [NodeConnectionType.Main, NodeConnectionType.AiTool].includes(type)
const maxConnections = (
[NodeConnectionTypes.Main, NodeConnectionTypes.AiTool] as NodeConnectionType[]
).includes(type)
? Infinity
: 1;
return {

View File

@@ -11,7 +11,7 @@ import type {
INodeTypeDescription,
INodeIssues,
} from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers, Workflow } from 'n8n-workflow';
import { NodeConnectionTypes, NodeHelpers, Workflow } from 'n8n-workflow';
import { v4 as uuid } from 'uuid';
import { mock } from 'vitest-mock-extended';
@@ -52,8 +52,8 @@ export const mockNodeTypeDescription = ({
name = SET_NODE_TYPE,
version = 1,
credentials = [],
inputs = [NodeConnectionType.Main],
outputs = [NodeConnectionType.Main],
inputs = [NodeConnectionTypes.Main],
outputs = [NodeConnectionTypes.Main],
codex = undefined,
properties = [],
}: {

View File

@@ -5,7 +5,7 @@ import { userEvent } from '@testing-library/user-event';
import { createRouter, createWebHistory } from 'vue-router';
import { computed, ref } from 'vue';
import type { INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import CanvasChat from './CanvasChat.vue';
import { createComponentRenderer } from '@/__tests__/render';
@@ -77,8 +77,8 @@ const mockNodeTypes: INodeTypeDescription[] = [
defaults: {
name: 'AI Agent',
},
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
version: 0,
group: [],
description: '',
@@ -96,7 +96,7 @@ const mockConnections = {
[
{
node: 'AI Agent',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],

View File

@@ -2,7 +2,7 @@ import type { ComputedRef, Ref } from 'vue';
import { computed, ref } from 'vue';
import { v4 as uuid } from 'uuid';
import type { ChatMessage, ChatMessageText } from '@n8n/chat/types';
import { NodeConnectionType, CHAT_TRIGGER_NODE_TYPE } from 'n8n-workflow';
import { NodeConnectionTypes, CHAT_TRIGGER_NODE_TYPE } from 'n8n-workflow';
import type {
ITaskData,
INodeExecutionData,
@@ -252,7 +252,7 @@ export function useChatMessaging({
const connectedMemoryInputs =
workflow.value.connectionsByDestinationNode?.[connectedNode.value.name]?.[
NodeConnectionType.AiMemory
NodeConnectionTypes.AiMemory
];
if (!connectedMemoryInputs) return [];
@@ -263,7 +263,9 @@ export function useChatMessaging({
const nodeResultData = getWorkflowResultDataByNodeName(memoryConnection.node);
const memoryOutputData = (nodeResultData ?? [])
.map((data) => get(data, ['data', NodeConnectionType.AiMemory, 0, 0, 'json']) as MemoryOutput)
.map(
(data) => get(data, ['data', NodeConnectionTypes.AiMemory, 0, 0, 'json']) as MemoryOutput,
)
.find((data) => data && data.action === 'saveContext');
return (memoryOutputData?.chatHistory ?? []).map((message, index) => {

View File

@@ -2,7 +2,7 @@ import type { ComputedRef, MaybeRef } from 'vue';
import { ref, computed, unref } from 'vue';
import {
CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE,
NodeConnectionType,
NodeConnectionTypes,
NodeHelpers,
} from 'n8n-workflow';
import type { INodeTypeDescription, Workflow, INode, INodeParameters } from 'n8n-workflow';
@@ -103,9 +103,9 @@ export function useChatTrigger({
// Validate if node has required AI connection types
if (
inputTypes.includes(NodeConnectionType.AiLanguageModel) &&
inputTypes.includes(NodeConnectionType.Main) &&
outputTypes.includes(NodeConnectionType.Main)
inputTypes.includes(NodeConnectionTypes.AiLanguageModel) &&
inputTypes.includes(NodeConnectionTypes.Main) &&
outputTypes.includes(NodeConnectionTypes.Main)
) {
isCustomChainOrAgent = true;
}

View File

@@ -11,7 +11,7 @@ import { createExpressionTelemetryPayload } from '@/utils/telemetryUtils';
import { useTelemetry } from '@/composables/useTelemetry';
import type { Segment } from '@/types/expressions';
import type { INodeProperties } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { outputTheme } from './ExpressionEditorModal/theme';
import ExpressionOutput from './InlineExpressionEditor/ExpressionOutput.vue';
import VirtualSchema from '@/components/VirtualSchema.vue';
@@ -172,7 +172,7 @@ const onResizeThrottle = useThrottleFn(onResize, 10);
:search="appliedSearch"
:nodes="parentNodes"
:mapping-enabled="!isReadOnly"
:connection-type="NodeConnectionType.Main"
:connection-type="NodeConnectionTypes.Main"
pane-type="input"
/>
</div>

View File

@@ -6,7 +6,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { createTestingPinia } from '@pinia/testing';
import { waitFor } from '@testing-library/vue';
import {
NodeConnectionType,
NodeConnectionTypes,
type IConnections,
type INodeExecutionData,
type IRunData,
@@ -32,18 +32,18 @@ const nodes = [
const render = (props: Partial<Props> = {}, pinData?: INodeExecutionData[], runData?: IRunData) => {
const connections: IConnections = {
[nodes[0].name]: {
[NodeConnectionType.Main]: [
[{ node: nodes[1].name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: nodes[1].name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
[nodes[1].name]: {
[NodeConnectionType.Main]: [
[{ node: nodes[2].name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: nodes[2].name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
[nodes[3].name]: {
[NodeConnectionType.AiMemory]: [
[{ node: nodes[2].name, type: NodeConnectionType.AiMemory, index: 0 }],
[NodeConnectionTypes.AiMemory]: [
[{ node: nodes[2].name, type: NodeConnectionTypes.AiMemory, index: 0 }],
],
},
};

View File

@@ -14,7 +14,7 @@ import { waitingNodeTooltip } from '@/utils/executionUtils';
import { uniqBy } from 'lodash-es';
import { N8nIcon, N8nRadioButtons, N8nText, N8nTooltip } from '@n8n/design-system';
import type { INodeInputConfiguration, INodeOutputConfiguration, Workflow } from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { type NodeConnectionType, NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
import { storeToRefs } from 'pinia';
import { computed, ref, watch } from 'vue';
import { useNDVStore } from '../stores/ndv.store';
@@ -143,8 +143,8 @@ const isActiveNodeConfig = computed(() => {
return (
inputs.length === 0 ||
(inputs.every((input) => filterOutConnectionType(input, NodeConnectionType.Main)) &&
outputs.find((output) => filterOutConnectionType(output, NodeConnectionType.Main)))
(inputs.every((input) => filterOutConnectionType(input, NodeConnectionTypes.Main)) &&
outputs.find((output) => filterOutConnectionType(output, NodeConnectionTypes.Main)))
);
});

View File

@@ -4,7 +4,7 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { computed, onMounted, onBeforeUnmount } from 'vue';
import NodeIcon from '@/components/NodeIcon.vue';
import { NodeConnectionType, type INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionTypes, type INodeTypeDescription } from 'n8n-workflow';
interface Props {
rootNode: INodeUi;
@@ -72,10 +72,10 @@ const connectedNodes = computed<
workflow.getChildNodes(rootName, 'ALL_NON_MAIN'),
),
[FloatingNodePosition.right]: getINodesFromNames(
workflow.getChildNodes(rootName, NodeConnectionType.Main, 1),
workflow.getChildNodes(rootName, NodeConnectionTypes.Main, 1),
).reverse(),
[FloatingNodePosition.left]: getINodesFromNames(
workflow.getParentNodes(rootName, NodeConnectionType.Main, 1),
workflow.getParentNodes(rootName, NodeConnectionTypes.Main, 1),
),
};
});

View File

@@ -4,17 +4,17 @@ import { setActivePinia } from 'pinia';
import { createTestingPinia } from '@pinia/testing';
import type { INodeUi } from '@/Interface';
import type { INodeTypeDescription, WorkflowParameters } from 'n8n-workflow';
import { NodeConnectionType, Workflow } from 'n8n-workflow';
import { NodeConnectionTypes, Workflow } from 'n8n-workflow';
const nodeType: INodeTypeDescription = {
displayName: 'OpenAI',
name: '@n8n/n8n-nodes-langchain.openAi',
version: [1],
inputs: [
{ type: NodeConnectionType.Main },
{ type: NodeConnectionType.AiTool, displayName: 'Tools' },
{ type: NodeConnectionTypes.Main },
{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' },
],
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
credentials: [
{
name: 'openAiApi',

View File

@@ -1,7 +1,7 @@
import { computed } from 'vue';
import {
CHAIN_LLM_LANGCHAIN_NODE_TYPE,
NodeConnectionType,
NodeConnectionTypes,
type IDataObject,
type INodeParameters,
} from 'n8n-workflow';
@@ -249,7 +249,7 @@ export const useActions = () => {
if (shouldPrependLLMChain(addedNodes)) {
addedNodes.unshift({ type: CHAIN_LLM_LANGCHAIN_NODE_TYPE, isAutoAdd: true });
connections.push({
from: { nodeIndex: 2, type: NodeConnectionType.AiLanguageModel },
from: { nodeIndex: 2, type: NodeConnectionTypes.AiLanguageModel },
to: { nodeIndex: 1 },
});
}

View File

@@ -1,4 +1,4 @@
import { NodeConnectionType, type INodeProperties, type INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionTypes, type INodeProperties, type INodeTypeDescription } from 'n8n-workflow';
import { useActionsGenerator } from './composables/useActionsGeneration';
describe('useActionsGenerator', () => {
@@ -14,8 +14,8 @@ describe('useActionsGenerator', () => {
defaults: {
name: 'Test',
},
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
properties: [],
};

View File

@@ -62,7 +62,8 @@ import { useI18n } from '@/composables/useI18n';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import type { SimplifiedNodeType } from '@/Interface';
import type { INodeTypeDescription, Themed } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { NodeConnectionType } from 'n8n-workflow';
import { useTemplatesStore } from '@/stores/templates.store';
import type { BaseTextKey } from '@/plugins/i18n';
import { camelCase } from 'lodash-es';
@@ -219,7 +220,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_DOCUMENT_LOADERS,
info: getSubcategoryInfo(AI_CATEGORY_DOCUMENT_LOADERS),
icon: 'file-import',
...getAISubcategoryProperties(NodeConnectionType.AiDocument),
...getAISubcategoryProperties(NodeConnectionTypes.AiDocument),
},
},
{
@@ -229,7 +230,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_LANGUAGE_MODELS,
info: getSubcategoryInfo(AI_CATEGORY_LANGUAGE_MODELS),
icon: 'language',
...getAISubcategoryProperties(NodeConnectionType.AiLanguageModel),
...getAISubcategoryProperties(NodeConnectionTypes.AiLanguageModel),
},
},
{
@@ -239,7 +240,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_MEMORY,
info: getSubcategoryInfo(AI_CATEGORY_MEMORY),
icon: 'brain',
...getAISubcategoryProperties(NodeConnectionType.AiMemory),
...getAISubcategoryProperties(NodeConnectionTypes.AiMemory),
},
},
{
@@ -249,7 +250,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_OUTPUTPARSER,
info: getSubcategoryInfo(AI_CATEGORY_OUTPUTPARSER),
icon: 'list',
...getAISubcategoryProperties(NodeConnectionType.AiOutputParser),
...getAISubcategoryProperties(NodeConnectionTypes.AiOutputParser),
},
},
{
@@ -259,7 +260,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_RETRIEVERS,
info: getSubcategoryInfo(AI_CATEGORY_RETRIEVERS),
icon: 'search',
...getAISubcategoryProperties(NodeConnectionType.AiRetriever),
...getAISubcategoryProperties(NodeConnectionTypes.AiRetriever),
},
},
{
@@ -269,7 +270,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_TEXT_SPLITTERS,
info: getSubcategoryInfo(AI_CATEGORY_TEXT_SPLITTERS),
icon: 'grip-lines-vertical',
...getAISubcategoryProperties(NodeConnectionType.AiTextSplitter),
...getAISubcategoryProperties(NodeConnectionTypes.AiTextSplitter),
},
},
{
@@ -280,7 +281,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_TOOLS,
info: getSubcategoryInfo(AI_CATEGORY_TOOLS),
icon: 'tools',
...getAISubcategoryProperties(NodeConnectionType.AiTool),
...getAISubcategoryProperties(NodeConnectionTypes.AiTool),
sections: [
{
key: 'popular',
@@ -297,7 +298,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_EMBEDDING,
info: getSubcategoryInfo(AI_CATEGORY_EMBEDDING),
icon: 'vector-square',
...getAISubcategoryProperties(NodeConnectionType.AiEmbedding),
...getAISubcategoryProperties(NodeConnectionTypes.AiEmbedding),
},
},
{
@@ -307,7 +308,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
title: AI_CATEGORY_VECTOR_STORES,
info: getSubcategoryInfo(AI_CATEGORY_VECTOR_STORES),
icon: 'project-diagram',
...getAISubcategoryProperties(NodeConnectionType.AiVectorStore),
...getAISubcategoryProperties(NodeConnectionTypes.AiVectorStore),
},
},
{

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed, watch } from 'vue';
import { createEventBus } from '@n8n/utils/event-bus';
import type { IRunData, Workflow } from 'n8n-workflow';
import { jsonParse, NodeHelpers, NodeConnectionType } from 'n8n-workflow';
import type { IRunData, Workflow, NodeConnectionType } from 'n8n-workflow';
import { jsonParse, NodeHelpers, NodeConnectionTypes } from 'n8n-workflow';
import type { IUpdateInformation, TargetItem } from '@/Interface';
import NodeSettings from '@/components/NodeSettings.vue';
@@ -160,16 +160,16 @@ const inputNodeName = computed<string | undefined>(() => {
: [];
const nonMainOutputs = nodeOutputs.filter((output) => {
if (typeof output === 'string') return output !== NodeConnectionType.Main;
if (typeof output === 'string') return output !== NodeConnectionTypes.Main;
return output.type !== NodeConnectionType.Main;
return output.type !== NodeConnectionTypes.Main;
});
const isSubNode = nonMainOutputs.length > 0;
if (isSubNode && activeNode.value) {
// For sub-nodes, we need to get their connected output node to determine the input
// because sub-nodes use specialized outputs (e.g. NodeConnectionType.AiTool)
// because sub-nodes use specialized outputs (e.g. NodeConnectionTypes.AiTool)
// instead of the standard Main output type
const connectedOutputNode = props.workflowObject.getChildNodes(
activeNode.value.name,
@@ -275,7 +275,7 @@ const maxInputRun = computed(() => {
const runData: IRunData | null = workflowRunData.value;
if (outputs.some((output) => output !== NodeConnectionType.Main)) {
if (outputs.some((output) => output !== NodeConnectionTypes.Main)) {
node = activeNode.value;
}
@@ -413,7 +413,7 @@ const onFeatureRequestClick = () => {
node_type: activeNode.value.type,
workflow_id: workflowsStore.workflowId,
push_ref: pushRef.value,
pane: NodeConnectionType.Main,
pane: NodeConnectionTypes.Main,
type: 'i-wish-this-node-would',
});
}

View File

@@ -4,11 +4,12 @@ import type {
INodeTypeDescription,
INodeParameters,
INodeProperties,
NodeConnectionType,
NodeParameterValue,
} from 'n8n-workflow';
import {
NodeHelpers,
NodeConnectionType,
NodeConnectionTypes,
deepCopy,
isINodePropertyCollectionList,
isINodePropertiesList,
@@ -139,7 +140,7 @@ const isExecutable = computed(() => {
);
const inputNames = NodeHelpers.getConnectionTypes(inputs);
if (!inputNames.includes(NodeConnectionType.Main) && !isTriggerNode.value) {
if (!inputNames.includes(NodeConnectionTypes.Main) && !isTriggerNode.value) {
return false;
}
}

View File

@@ -8,7 +8,7 @@ import {
import { useNDVStore } from '@/stores/ndv.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import type { INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { computed } from 'vue';
import { useExternalHooks } from '@/composables/useExternalHooks';
@@ -130,7 +130,7 @@ function onTabSelect(tab: string) {
node_type: activeNode.value?.type,
workflow_id: workflowsStore.workflowId,
push_ref: props.pushRef,
pane: NodeConnectionType.Main,
pane: NodeConnectionTypes.Main,
type: 'docs',
});
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import {
NodeConnectionType,
NodeConnectionTypes,
type IRunData,
type IRunExecutionData,
type Workflow,
@@ -237,7 +237,7 @@ const allToolsWereUnusedNotice = computed(() => {
const toolsAvailable = props.workflow.getParentNodes(
node.value.name,
NodeConnectionType.AiTool,
NodeConnectionTypes.AiTool,
1,
);
const toolsUsedInLatestRun = toolsAvailable.filter(

View File

@@ -1,5 +1,5 @@
import {
NodeConnectionType,
NodeConnectionTypes,
type INode,
type INodeProperties,
type INodeTypeDescription,
@@ -91,8 +91,8 @@ export const EXECUTE_WORKFLOW_NODE_TYPE_TEST: INodeTypeDescription = {
subtitle: '={{"Workflow: " + $parameter["workflowId"]}}',
description: 'Execute another workflow',
defaults: { name: 'Execute Workflow', color: '#ff6d5a' },
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
properties: [
{
displayName: 'Operation',

View File

@@ -1,22 +1,26 @@
<script setup lang="ts">
import { useStorage } from '@/composables/useStorage';
import { saveAs } from 'file-saver';
import {
type IBinaryData,
type IConnectedNode,
type IDataObject,
type INodeExecutionData,
type INodeOutputConfiguration,
type IRunData,
type IRunExecutionData,
type ITaskMetadata,
type NodeError,
type NodeHint,
TRIMMED_TASK_DATA_CONNECTIONS_KEY,
type Workflow,
parseErrorMetadata,
import type {
IBinaryData,
IConnectedNode,
IDataObject,
INodeExecutionData,
INodeOutputConfiguration,
IRunData,
IRunExecutionData,
ITaskMetadata,
NodeError,
NodeHint,
Workflow,
NodeConnectionType,
} from 'n8n-workflow';
import {
parseErrorMetadata,
NodeConnectionTypes,
NodeHelpers,
TRIMMED_TASK_DATA_CONNECTIONS_KEY,
} from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { computed, defineAsyncComponent, onBeforeUnmount, onMounted, ref, toRef, watch } from 'vue';
import type {
@@ -164,7 +168,7 @@ const emit = defineEmits<{
];
}>();
const connectionType = ref<NodeConnectionType>(NodeConnectionType.Main);
const connectionType = ref<NodeConnectionType>(NodeConnectionTypes.Main);
const dataSize = ref(0);
const showData = ref(false);
const userEnabledShowData = ref(false);
@@ -1082,7 +1086,7 @@ function getRunLabel(option: number) {
function getRawInputData(
runIndex: number,
outputIndex: number,
connectionType: NodeConnectionType = NodeConnectionType.Main,
connectionType: NodeConnectionType = NodeConnectionTypes.Main,
): INodeExecutionData[] {
let inputData: INodeExecutionData[] = [];
@@ -1130,7 +1134,7 @@ function getFilteredData(data: INodeExecutionData[]): INodeExecutionData[] {
function getDataCount(
runIndex: number,
outputIndex: number,
connectionType: NodeConnectionType = NodeConnectionType.Main,
connectionType: NodeConnectionType = NodeConnectionTypes.Main,
) {
if (!node.value) {
return 0;
@@ -1165,7 +1169,7 @@ function init() {
const outputs = getResolvedNodeOutputs();
outputTypes = NodeHelpers.getConnectionTypes(outputs);
}
connectionType.value = outputTypes.length === 0 ? NodeConnectionType.Main : outputTypes[0];
connectionType.value = outputTypes.length === 0 ? NodeConnectionTypes.Main : outputTypes[0];
if (binaryData.value.length > 0) {
ndvStore.setPanelDisplayMode({
pane: props.paneType,

View File

@@ -9,8 +9,8 @@ import hljs from 'highlight.js/lib/core';
import { useClipboard } from '@/composables/useClipboard';
import { useI18n } from '@/composables/useI18n';
import { useToast } from '@/composables/useToast';
import { NodeConnectionType } from 'n8n-workflow';
import type { NodeError, IDataObject } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { NodeConnectionType, NodeError, IDataObject } from 'n8n-workflow';
const props = defineProps<{
runData: IAiDataContent;
@@ -29,13 +29,16 @@ const contentParsed = ref(false);
const parsedRun = ref(undefined as ParsedAiContent | undefined);
function getInitialExpandedState() {
const collapsedTypes = {
input: [NodeConnectionType.AiDocument, NodeConnectionType.AiTextSplitter],
input: [
NodeConnectionTypes.AiDocument,
NodeConnectionTypes.AiTextSplitter,
] as NodeConnectionType[],
output: [
NodeConnectionType.AiDocument,
NodeConnectionType.AiEmbedding,
NodeConnectionType.AiTextSplitter,
NodeConnectionType.AiVectorStore,
],
NodeConnectionTypes.AiDocument,
NodeConnectionTypes.AiEmbedding,
NodeConnectionTypes.AiTextSplitter,
NodeConnectionTypes.AiVectorStore,
] as NodeConnectionType[],
};
return !collapsedTypes[props.runData.inOut].includes(props.runData.type);

View File

@@ -1,5 +1,5 @@
import type { IDataObject, INodeExecutionData } from 'n8n-workflow';
import { isObjectEmpty, NodeConnectionType } from 'n8n-workflow';
import type { IDataObject, INodeExecutionData, NodeConnectionType } from 'n8n-workflow';
import { isObjectEmpty, NodeConnectionTypes } from 'n8n-workflow';
interface MemoryMessage {
lc: number;
@@ -15,7 +15,7 @@ interface LmGeneration {
message: MemoryMessage;
}
type ExcludedKeys = NodeConnectionType.Main | NodeConnectionType.AiChain;
type ExcludedKeys = typeof NodeConnectionTypes.Main | typeof NodeConnectionTypes.AiChain;
type AllowedEndpointType = Exclude<NodeConnectionType, ExcludedKeys>;
const fallbackParser = (execData: IDataObject) => ({
@@ -31,7 +31,7 @@ const outputTypeParsers: {
parsed: boolean;
};
} = {
[NodeConnectionType.AiLanguageModel](execData: IDataObject) {
[NodeConnectionTypes.AiLanguageModel](execData: IDataObject) {
const response = (execData.response as IDataObject) ?? execData;
if (!response) throw new Error('No response from Language Model');
@@ -50,7 +50,7 @@ const outputTypeParsers: {
// Use the memory parser if the response is a memory-like(chat) object
if (response.messages && Array.isArray(response.messages)) {
return outputTypeParsers[NodeConnectionType.AiMemory](execData);
return outputTypeParsers[NodeConnectionTypes.AiMemory](execData);
}
if (response.generations) {
@@ -82,9 +82,9 @@ const outputTypeParsers: {
parsed: true,
};
},
[NodeConnectionType.AiTool]: fallbackParser,
[NodeConnectionType.AiAgent]: fallbackParser,
[NodeConnectionType.AiMemory](execData: IDataObject) {
[NodeConnectionTypes.AiTool]: fallbackParser,
[NodeConnectionTypes.AiAgent]: fallbackParser,
[NodeConnectionTypes.AiMemory](execData: IDataObject) {
const chatHistory =
execData.chatHistory ??
execData.messages ??
@@ -153,9 +153,9 @@ const outputTypeParsers: {
return fallbackParser(execData);
},
[NodeConnectionType.AiOutputParser]: fallbackParser,
[NodeConnectionType.AiRetriever]: fallbackParser,
[NodeConnectionType.AiVectorStore](execData: IDataObject) {
[NodeConnectionTypes.AiOutputParser]: fallbackParser,
[NodeConnectionTypes.AiRetriever]: fallbackParser,
[NodeConnectionTypes.AiVectorStore](execData: IDataObject) {
if (execData.documents) {
return {
type: 'json',
@@ -166,7 +166,7 @@ const outputTypeParsers: {
return fallbackParser(execData);
},
[NodeConnectionType.AiEmbedding](execData: IDataObject) {
[NodeConnectionTypes.AiEmbedding](execData: IDataObject) {
if (execData.documents) {
return {
type: 'json',
@@ -177,7 +177,7 @@ const outputTypeParsers: {
return fallbackParser(execData);
},
[NodeConnectionType.AiDocument](execData: IDataObject) {
[NodeConnectionTypes.AiDocument](execData: IDataObject) {
if (execData.documents) {
return {
type: 'json',
@@ -188,7 +188,7 @@ const outputTypeParsers: {
return fallbackParser(execData);
},
[NodeConnectionType.AiTextSplitter](execData: IDataObject) {
[NodeConnectionTypes.AiTextSplitter](execData: IDataObject) {
const arrayData = Array.isArray(execData.response)
? execData.response
: [execData.textSplitter];
@@ -213,7 +213,11 @@ export const useAiContentParsers = () => {
executionData: INodeExecutionData[],
endpointType: NodeConnectionType,
): ParsedAiContent => {
if ([NodeConnectionType.AiChain, NodeConnectionType.Main].includes(endpointType)) {
if (
([NodeConnectionTypes.AiChain, NodeConnectionTypes.Main] as NodeConnectionType[]).includes(
endpointType,
)
) {
return executionData.map((data) => ({ raw: data.json, parsedContent: null }));
}

View File

@@ -1,6 +1,6 @@
import { createTestNode, createTestWorkflowObject } from '@/__tests__/mocks';
import { createAiData, getTreeNodeData } from '@/components/RunDataAi/utils';
import { type ITaskData, NodeConnectionType } from 'n8n-workflow';
import { type ITaskData, NodeConnectionTypes } from 'n8n-workflow';
describe(getTreeNodeData, () => {
function createTaskData(partialData: Partial<ITaskData>): ITaskData {
@@ -22,9 +22,9 @@ describe(getTreeNodeData, () => {
createTestNode({ name: 'C' }),
],
connections: {
B: { ai_tool: [[{ node: 'A', type: NodeConnectionType.AiTool, index: 0 }]] },
B: { ai_tool: [[{ node: 'A', type: NodeConnectionTypes.AiTool, index: 0 }]] },
C: {
ai_languageModel: [[{ node: 'B', type: NodeConnectionType.AiLanguageModel, index: 0 }]],
ai_languageModel: [[{ node: 'B', type: NodeConnectionTypes.AiLanguageModel, index: 0 }]],
},
},
});

View File

@@ -13,7 +13,7 @@ import {
mockNodeTypeDescription,
} from '@/__tests__/mocks';
import { mockedStore } from '@/__tests__/utils';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { SET_NODE_TYPE } from '@/constants';
vi.mock('vue-router', () => {
@@ -53,8 +53,8 @@ describe('NodesPinning', () => {
const nodeTypesStore = mockedStore(useNodeTypesStore);
const nodeTypeDescription = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
});
nodeTypesStore.nodeTypes = {
node: { 1: nodeTypeDescription },

View File

@@ -15,7 +15,7 @@ import { mock } from 'vitest-mock-extended';
import type { IWorkflowDb } from '@/Interface';
import {
createResultOk,
NodeConnectionType,
NodeConnectionTypes,
type IDataObject,
type INodeExecutionData,
} from 'n8n-workflow';
@@ -96,11 +96,11 @@ async function setupStore() {
...defaultNodeDescriptions,
mockNodeTypeDescription({
name: MANUAL_TRIGGER_NODE_TYPE,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
}),
mockNodeTypeDescription({
name: IF_NODE_TYPE,
outputs: [NodeConnectionType.Main, NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main, NodeConnectionTypes.Main],
}),
]);
workflowsStore.workflow = workflow;

View File

@@ -22,7 +22,8 @@ import { executionDataToJson } from '@/utils/nodeTypesUtils';
import { N8nText } from '@n8n/design-system';
import {
createResultError,
NodeConnectionType,
type NodeConnectionType,
NodeConnectionTypes,
type IConnectedNode,
type IDataObject,
} from 'n8n-workflow';
@@ -70,7 +71,7 @@ const props = withDefaults(defineProps<Props>(), {
runIndex: 0,
outputIndex: 0,
totalRuns: 1,
connectionType: NodeConnectionType.Main,
connectionType: NodeConnectionTypes.Main,
search: '',
mappingEnabled: false,
});

View File

@@ -5,7 +5,7 @@ import Canvas from '@/components/canvas/Canvas.vue';
import { createPinia, setActivePinia } from 'pinia';
import type { CanvasConnection, CanvasNode } from '@/types';
import { createCanvasConnection, createCanvasNodeElement } from '@/__tests__/data';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useVueFlow } from '@vue-flow/core';
@@ -59,7 +59,7 @@ describe('Canvas', () => {
data: {
outputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -72,7 +72,7 @@ describe('Canvas', () => {
data: {
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],

View File

@@ -36,7 +36,7 @@ import type {
import { MarkerType, PanelPosition, useVueFlow, VueFlow } from '@vue-flow/core';
import { MiniMap } from '@vue-flow/minimap';
import { onKeyDown, onKeyUp, useThrottleFn } from '@vueuse/core';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import {
computed,
nextTick,
@@ -460,7 +460,7 @@ onEdgeMouseEnter(({ edge }) => {
onEdgeMouseMove(
useThrottleFn(({ edge, event }) => {
const type = edge.data.source.type;
if (type !== NodeConnectionType.AiTool) {
if (type !== NodeConnectionTypes.AiTool) {
return;
}

View File

@@ -5,7 +5,7 @@ import { BaseEdge } from '@vue-flow/core';
import { computed, onMounted, ref, useCssModule } from 'vue';
import { getEdgeRenderData } from './utils';
import { useCanvas } from '@/composables/useCanvas';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { parseCanvasConnectionHandleString } from '@/utils/canvasUtils';
const props = defineProps<ConnectionLineProps>();
@@ -26,7 +26,7 @@ const classes = computed(() => {
});
const edgeColor = computed(() => {
if (connectionType.value !== NodeConnectionType.Main) {
if (connectionType.value !== NodeConnectionTypes.Main) {
return 'var(--node-type-supplemental-color)';
} else {
return 'var(--color-foreground-xdark)';
@@ -34,7 +34,7 @@ const edgeColor = computed(() => {
});
const edgeStyle = computed(() => ({
...(connectionType.value === NodeConnectionType.Main ? {} : { strokeDasharray: '8,8' }),
...(connectionType.value === NodeConnectionTypes.Main ? {} : { strokeDasharray: '8,8' }),
strokeWidth: 2,
stroke: edgeColor.value,
}));

View File

@@ -2,7 +2,7 @@ import { createComponentRenderer } from '@/__tests__/render';
import { createTestingPinia } from '@pinia/testing';
import userEvent from '@testing-library/user-event';
import { Position } from '@vue-flow/core';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { setActivePinia } from 'pinia';
import CanvasEdge, { type CanvasEdgeProps } from './CanvasEdge.vue';
@@ -15,8 +15,8 @@ const DEFAULT_PROPS = {
targetPosition: Position.Bottom,
data: {
status: undefined,
source: { index: 0, type: NodeConnectionType.Main },
target: { index: 0, type: NodeConnectionType.Main },
source: { index: 0, type: NodeConnectionTypes.Main },
target: { index: 0, type: NodeConnectionTypes.Main },
},
} satisfies Partial<CanvasEdgeProps>;
const renderComponent = createComponentRenderer(CanvasEdge, {
@@ -159,7 +159,7 @@ describe('CanvasEdge', () => {
data: {
...DEFAULT_PROPS.data,
source: {
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
},
},
sourceX: 0,

View File

@@ -4,7 +4,7 @@ import type { CanvasConnectionData } from '@/types';
import { isValidNodeConnectionType } from '@/utils/typeGuards';
import type { Connection, EdgeProps } from '@vue-flow/core';
import { BaseEdge, EdgeLabelRenderer } from '@vue-flow/core';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { computed, ref, toRef, useCssModule, watch } from 'vue';
import CanvasEdgeToolbar from './CanvasEdgeToolbar.vue';
import { getEdgeRenderData } from './utils';
@@ -30,7 +30,7 @@ const $style = useCssModule();
const connectionType = computed(() =>
isValidNodeConnectionType(props.data.source.type)
? props.data.source.type
: NodeConnectionType.Main,
: NodeConnectionTypes.Main,
);
const delayedHovered = ref(props.hovered);
@@ -54,7 +54,7 @@ watch(
const renderToolbar = computed(() => (props.selected || delayedHovered.value) && !props.readOnly);
const isMainConnection = computed(() => data.value.source.type === NodeConnectionType.Main);
const isMainConnection = computed(() => data.value.source.type === NodeConnectionTypes.Main);
const status = computed(() => props.data.status);

View File

@@ -1,7 +1,8 @@
<script lang="ts" setup>
import { useI18n } from '@/composables/useI18n';
import { computed, useCssModule } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import type { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
const emit = defineEmits<{
add: [];
@@ -20,7 +21,7 @@ const classes = computed(() => ({
[$style.canvasEdgeToolbar]: true,
}));
const isAddButtonVisible = computed(() => props.type === NodeConnectionType.Main);
const isAddButtonVisible = computed(() => props.type === NodeConnectionTypes.Main);
function onAdd() {
emit('add');

View File

@@ -1,6 +1,7 @@
import type { EdgeProps } from '@vue-flow/core';
import { getBezierPath, getSmoothStepPath, Position } from '@vue-flow/core';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { NodeConnectionType } from 'n8n-workflow';
const EDGE_PADDING_BOTTOM = 130;
const EDGE_PADDING_X = 40;
@@ -15,7 +16,7 @@ export function getEdgeRenderData(
'sourceX' | 'sourceY' | 'sourcePosition' | 'targetX' | 'targetY' | 'targetPosition'
>,
{
connectionType = NodeConnectionType.Main,
connectionType = NodeConnectionTypes.Main,
}: {
connectionType?: NodeConnectionType;
} = {},
@@ -23,7 +24,7 @@ export function getEdgeRenderData(
const { targetX, targetY, sourceX, sourceY, sourcePosition, targetPosition } = props;
const isConnectorStraight = sourceY === targetY;
if (!isRightOfSourceHandle(sourceX, targetX) || connectionType !== NodeConnectionType.Main) {
if (!isRightOfSourceHandle(sourceX, targetX) || connectionType !== NodeConnectionTypes.Main) {
const segment = getBezierPath(props);
return {
segments: [segment],

View File

@@ -1,5 +1,5 @@
import CanvasHandleRenderer from '@/components/canvas/elements/handles/CanvasHandleRenderer.vue';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { createComponentRenderer } from '@/__tests__/render';
import { CanvasNodeHandleKey } from '@/constants';
import { ref } from 'vue';
@@ -16,7 +16,7 @@ describe('CanvasHandleRenderer', () => {
const { container } = renderComponent({
props: {
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
position: 'left',
offset: { left: '10px', top: '10px' },
@@ -37,7 +37,7 @@ describe('CanvasHandleRenderer', () => {
const { container } = renderComponent({
props: {
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
position: 'right',
offset: { right: '10px', bottom: '10px' },
@@ -58,7 +58,7 @@ describe('CanvasHandleRenderer', () => {
const { container } = renderComponent({
props: {
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
position: 'top',
offset: { top: '10px', left: '5px' },
@@ -80,7 +80,7 @@ describe('CanvasHandleRenderer', () => {
const { getByText } = renderComponent({
props: {
mode: 'input',
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
position: 'top',
offset: { top: '10px', left: '5px' },

View File

@@ -5,7 +5,7 @@ import type { CanvasConnectionPort, CanvasElementPortWithRenderData } from '@/ty
import { CanvasConnectionMode } from '@/types';
import type { ValidConnectionFunc } from '@vue-flow/core';
import { Handle } from '@vue-flow/core';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import CanvasHandleMainInput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainInput.vue';
import CanvasHandleMainOutput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainOutput.vue';
import CanvasHandleNonMainInput from '@/components/canvas/elements/handles/render-types/CanvasHandleNonMainInput.vue';
@@ -58,13 +58,13 @@ const connectionsLimitReached = computed(() => {
const isConnectableStart = computed(() => {
if (connectionsLimitReached.value) return false;
return props.mode === CanvasConnectionMode.Output || props.type !== NodeConnectionType.Main;
return props.mode === CanvasConnectionMode.Output || props.type !== NodeConnectionTypes.Main;
});
const isConnectableEnd = computed(() => {
if (connectionsLimitReached.value) return false;
return props.mode === CanvasConnectionMode.Input || props.type !== NodeConnectionType.Main;
return props.mode === CanvasConnectionMode.Input || props.type !== NodeConnectionTypes.Main;
});
const isConnected = computed(() => props.connectionsCount > 0);
@@ -91,13 +91,13 @@ const RenderType = () => {
let Component;
if (props.mode === CanvasConnectionMode.Output) {
if (props.type === NodeConnectionType.Main) {
if (props.type === NodeConnectionTypes.Main) {
Component = CanvasHandleMainOutput;
} else {
Component = CanvasHandleNonMainOutput;
}
} else {
if (props.type === NodeConnectionType.Main) {
if (props.type === NodeConnectionTypes.Main) {
Component = CanvasHandleMainInput;
} else {
Component = CanvasHandleNonMainInput;

View File

@@ -1,7 +1,7 @@
import CanvasNode from '@/components/canvas/elements/nodes/CanvasNode.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { createPinia, setActivePinia } from 'pinia';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { fireEvent } from '@testing-library/vue';
import { createCanvasNodeData, createCanvasNodeProps, createCanvasProvide } from '@/__tests__/data';
import { CanvasNodeRenderType } from '@/types';
@@ -61,13 +61,13 @@ describe('CanvasNode', () => {
...createCanvasNodeProps({
data: {
inputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
],
outputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
],
},
}),
@@ -92,9 +92,9 @@ describe('CanvasNode', () => {
...createCanvasNodeProps({
data: {
inputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.AiAgent, index: 0, required: true },
{ type: NodeConnectionType.AiTool, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.AiAgent, index: 0, required: true },
{ type: NodeConnectionTypes.AiTool, index: 0 },
],
outputs: [],
},

View File

@@ -1,6 +1,6 @@
import CanvasNodeDefault from '@/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { createCanvasNodeProvide, createCanvasProvide } from '@/__tests__/data';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
@@ -40,7 +40,7 @@ describe('CanvasNodeDefault', () => {
provide: {
...createCanvasNodeProvide({
data: {
inputs: [{ type: NodeConnectionType.Main, index: 0 }],
inputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
},
}),
},
@@ -58,9 +58,9 @@ describe('CanvasNodeDefault', () => {
...createCanvasNodeProvide({
data: {
inputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
],
},
}),
@@ -80,7 +80,7 @@ describe('CanvasNodeDefault', () => {
provide: {
...createCanvasNodeProvide({
data: {
outputs: [{ type: NodeConnectionType.Main, index: 0 }],
outputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
},
}),
},
@@ -98,9 +98,9 @@ describe('CanvasNodeDefault', () => {
...createCanvasNodeProvide({
data: {
outputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
],
},
}),
@@ -173,17 +173,17 @@ describe('CanvasNodeDefault', () => {
...createCanvasNodeProvide({
data: {
disabled: true,
inputs: [{ type: NodeConnectionType.Main, index: 0 }],
outputs: [{ type: NodeConnectionType.Main, index: 0 }],
inputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
outputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
connections: {
[CanvasConnectionMode.Input]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'node', type: NodeConnectionTypes.Main, index: 0 }],
],
},
[CanvasConnectionMode.Output]: {
[NodeConnectionType.Main]: [
[{ node: 'node', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'node', type: NodeConnectionTypes.Main, index: 0 }],
],
},
},
@@ -251,10 +251,10 @@ describe('CanvasNodeDefault', () => {
...createCanvasNodeProvide({
data: {
inputs: [
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.AiTool, index: 0 },
{ type: NodeConnectionType.AiDocument, index: 0, required: true },
{ type: NodeConnectionType.AiMemory, index: 0, required: true },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.AiTool, index: 0 },
{ type: NodeConnectionTypes.AiDocument, index: 0, required: true },
{ type: NodeConnectionTypes.AiMemory, index: 0, required: true },
],
render: {
type: CanvasNodeRenderType.Default,

View File

@@ -1,6 +1,6 @@
import { VIEWS } from '@/constants';
import type { ChatRequest } from '@/types/assistant.types';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
export const PAYLOAD_SIZE_FOR_1_PASS = 4;
export const PAYLOAD_SIZE_FOR_2_PASSES = 2;
@@ -115,7 +115,7 @@ export const SUPPORT_CHAT_TEST_PAYLOAD: ChatRequest.RequestPayload = {
[
{
node: 'Edit Fields',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -126,22 +126,22 @@ export const SUPPORT_CHAT_TEST_PAYLOAD: ChatRequest.RequestPayload = {
[
{
node: 'Bad request no chat found',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
{
node: 'Slack',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
{
node: 'Edit Fields1',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
{
node: 'Edit Fields2',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],

View File

@@ -1,6 +1,6 @@
import type { Ref } from 'vue';
import { ref } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { Workflow, INode, NodeApiError } from 'n8n-workflow';
import { setActivePinia } from 'pinia';
@@ -213,8 +213,8 @@ describe('useCanvasMapping', () => {
const nodes = [manualTriggerNode, setNode];
const connections = {
[manualTriggerNode.name]: {
[NodeConnectionType.Main]: [
[{ node: setNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: setNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -230,31 +230,31 @@ describe('useCanvasMapping', () => {
});
expect(mappedNodes.value[0]?.data?.connections[CanvasConnectionMode.Output]).toHaveProperty(
NodeConnectionType.Main,
NodeConnectionTypes.Main,
);
expect(
mappedNodes.value[0]?.data?.connections[CanvasConnectionMode.Output][
NodeConnectionType.Main
NodeConnectionTypes.Main
][0]?.[0],
).toEqual(
expect.objectContaining({
node: setNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
);
expect(mappedNodes.value[1]?.data?.connections[CanvasConnectionMode.Input]).toHaveProperty(
NodeConnectionType.Main,
NodeConnectionTypes.Main,
);
expect(
mappedNodes.value[1]?.data?.connections[CanvasConnectionMode.Input][
NodeConnectionType.Main
NodeConnectionTypes.Main
][0]?.[0],
).toEqual(
expect.objectContaining({
node: manualTriggerNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
);
@@ -390,7 +390,7 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }, { json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }, { json: {} }]],
},
},
]);
@@ -403,7 +403,7 @@ describe('useCanvasMapping', () => {
expect(nodeExecutionRunDataOutputMapById.value).toEqual({
[nodes[0].id]: {
[NodeConnectionType.Main]: {
[NodeConnectionTypes.Main]: {
0: {
iterations: 1,
total: 2,
@@ -433,8 +433,8 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }]],
[NodeConnectionType.AiAgent]: [[{ json: {} }, { json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }]],
[NodeConnectionTypes.AiAgent]: [[{ json: {} }, { json: {} }]],
},
},
];
@@ -445,7 +445,7 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }, { json: {} }, { json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }, { json: {} }, { json: {} }]],
},
},
];
@@ -462,13 +462,13 @@ describe('useCanvasMapping', () => {
expect(nodeExecutionRunDataOutputMapById.value).toEqual({
node1: {
[NodeConnectionType.Main]: {
[NodeConnectionTypes.Main]: {
0: {
iterations: 1,
total: 1,
},
},
[NodeConnectionType.AiAgent]: {
[NodeConnectionTypes.AiAgent]: {
0: {
iterations: 1,
total: 2,
@@ -476,7 +476,7 @@ describe('useCanvasMapping', () => {
},
},
node2: {
[NodeConnectionType.Main]: {
[NodeConnectionTypes.Main]: {
0: {
iterations: 1,
total: 3,
@@ -501,7 +501,7 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }]],
},
},
{
@@ -509,7 +509,7 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }, { json: {} }, { json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }, { json: {} }, { json: {} }]],
},
},
{
@@ -517,7 +517,7 @@ describe('useCanvasMapping', () => {
executionTime: 0,
source: [],
data: {
[NodeConnectionType.Main]: [[{ json: {} }, { json: {} }]],
[NodeConnectionTypes.Main]: [[{ json: {} }, { json: {} }]],
},
},
]);
@@ -530,7 +530,7 @@ describe('useCanvasMapping', () => {
expect(nodeExecutionRunDataOutputMapById.value).toEqual({
[nodes[0].id]: {
[NodeConnectionType.Main]: {
[NodeConnectionTypes.Main]: {
0: {
iterations: 3,
total: 6,
@@ -1120,8 +1120,8 @@ describe('useCanvasMapping', () => {
const nodes = [manualTriggerNode, setNode];
const connections = {
[manualTriggerNode.name]: {
[NodeConnectionType.Main]: [
[{ node: setNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: setNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -1138,13 +1138,13 @@ describe('useCanvasMapping', () => {
const source = manualTriggerNode.id;
const sourceHandle = createCanvasConnectionHandleString({
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
mode: CanvasConnectionMode.Output,
});
const target = setNode.id;
const targetHandle = createCanvasConnectionHandleString({
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
mode: CanvasConnectionMode.Input,
});
@@ -1161,13 +1161,13 @@ describe('useCanvasMapping', () => {
source: {
node: manualTriggerNode.name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
status: undefined,
target: {
node: setNode.name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
id: connectionId,
@@ -1187,11 +1187,11 @@ describe('useCanvasMapping', () => {
const nodes = [manualTriggerNode, setNode];
const connections = {
[manualTriggerNode.name]: {
[NodeConnectionType.AiTool]: [
[{ node: setNode.name, type: NodeConnectionType.AiTool, index: 0 }],
[NodeConnectionTypes.AiTool]: [
[{ node: setNode.name, type: NodeConnectionTypes.AiTool, index: 0 }],
],
[NodeConnectionType.AiDocument]: [
[{ node: setNode.name, type: NodeConnectionType.AiDocument, index: 1 }],
[NodeConnectionTypes.AiDocument]: [
[{ node: setNode.name, type: NodeConnectionTypes.AiDocument, index: 1 }],
],
},
};
@@ -1208,13 +1208,13 @@ describe('useCanvasMapping', () => {
const sourceA = manualTriggerNode.id;
const sourceHandleA = createCanvasConnectionHandleString({
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
mode: CanvasConnectionMode.Output,
});
const targetA = setNode.id;
const targetHandleA = createCanvasConnectionHandleString({
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
mode: CanvasConnectionMode.Input,
});
@@ -1227,13 +1227,13 @@ describe('useCanvasMapping', () => {
const sourceB = manualTriggerNode.id;
const sourceHandleB = createCanvasConnectionHandleString({
type: NodeConnectionType.AiDocument,
type: NodeConnectionTypes.AiDocument,
index: 0,
mode: CanvasConnectionMode.Output,
});
const targetB = setNode.id;
const targetHandleB = createCanvasConnectionHandleString({
type: NodeConnectionType.AiDocument,
type: NodeConnectionTypes.AiDocument,
index: 1,
mode: CanvasConnectionMode.Input,
});
@@ -1250,13 +1250,13 @@ describe('useCanvasMapping', () => {
source: {
node: manualTriggerNode.name,
index: 0,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
},
status: undefined,
target: {
node: setNode.name,
index: 0,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
},
},
id: connectionIdA,
@@ -1273,13 +1273,13 @@ describe('useCanvasMapping', () => {
source: {
node: manualTriggerNode.name,
index: 0,
type: NodeConnectionType.AiDocument,
type: NodeConnectionTypes.AiDocument,
},
status: undefined,
target: {
node: setNode.name,
index: 1,
type: NodeConnectionType.AiDocument,
type: NodeConnectionTypes.AiDocument,
},
},
id: connectionIdB,

View File

@@ -38,7 +38,7 @@ import type {
Workflow,
} from 'n8n-workflow';
import {
NodeConnectionType,
NodeConnectionTypes,
NodeHelpers,
SEND_AND_WAIT_OPERATION,
WAIT_INDEFINITELY,
@@ -194,7 +194,7 @@ export function useCanvasMapping({
const labelSizes: CanvasNodeDefaultRenderLabelSize[] = ['small', 'medium', 'large'];
const labelSizeIndexes = ports.reduce<number[]>(
(sizeAcc, input) => {
if (input.type === NodeConnectionType.Main) {
if (input.type === NodeConnectionTypes.Main) {
sizeAcc.push(getLabelSize(input.label ?? ''));
}

View File

@@ -2,7 +2,7 @@ import { useCanvasNode } from '@/composables/useCanvasNode';
import { inject, ref } from 'vue';
import type { CanvasNodeData, CanvasNodeInjectionData } from '../types';
import { CanvasConnectionMode, CanvasNodeRenderType } from '../types';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
vi.mock('vue', async () => {
const actual = await vi.importActual('vue');
@@ -47,8 +47,8 @@ describe('useCanvasNode', () => {
type: 'nodeType1',
typeVersion: 1,
disabled: true,
inputs: [{ type: NodeConnectionType.Main, index: 0 }],
outputs: [{ type: NodeConnectionType.Main, index: 0 }],
inputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
outputs: [{ type: NodeConnectionTypes.Main, index: 0 }],
connections: {
[CanvasConnectionMode.Input]: { '0': [] },
[CanvasConnectionMode.Output]: {},
@@ -77,8 +77,8 @@ describe('useCanvasNode', () => {
expect(result.label.value).toBe('Node 1');
expect(result.name.value).toBe('Node 1');
expect(result.inputs.value).toEqual([{ type: NodeConnectionType.Main, index: 0 }]);
expect(result.outputs.value).toEqual([{ type: NodeConnectionType.Main, index: 0 }]);
expect(result.inputs.value).toEqual([{ type: NodeConnectionTypes.Main, index: 0 }]);
expect(result.outputs.value).toEqual([{ type: NodeConnectionTypes.Main, index: 0 }]);
expect(result.connections.value).toEqual({
[CanvasConnectionMode.Input]: { '0': [] },
[CanvasConnectionMode.Output]: {},

View File

@@ -5,7 +5,7 @@
import { CanvasNodeHandleKey } from '@/constants';
import { computed, inject } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { CanvasConnectionMode } from '@/types';
export function useCanvasNodeHandle() {
@@ -17,7 +17,7 @@ export function useCanvasNodeHandle() {
const isReadOnly = computed(() => handle?.isReadOnly.value);
const isRequired = computed(() => handle?.isRequired.value);
const maxConnections = computed(() => handle?.maxConnections.value);
const type = computed(() => handle?.type.value ?? NodeConnectionType.Main);
const type = computed(() => handle?.type.value ?? NodeConnectionTypes.Main);
const mode = computed(() => handle?.mode.value ?? CanvasConnectionMode.Input);
const index = computed(() => handle?.index.value ?? 0);
const runData = computed(() => handle?.runData.value);

View File

@@ -7,7 +7,7 @@ import type {
INodeConnections,
WorkflowExecuteMode,
} from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
import { useCanvasOperations } from '@/composables/useCanvasOperations';
import type { CanvasConnection, CanvasNode } from '@/types';
import { CanvasConnectionMode } from '@/types';
@@ -350,11 +350,11 @@ describe('useCanvasOperations', () => {
workflowObject.getNode = vi.fn().mockReturnValue(node);
vi.spyOn(NodeHelpers, 'getNodeOutputs').mockReturnValueOnce([
{ type: NodeConnectionType.AiTool },
{ type: NodeConnectionTypes.AiTool },
]);
vi.spyOn(NodeHelpers, 'getConnectionTypes')
.mockReturnValueOnce([NodeConnectionType.AiTool])
.mockReturnValueOnce([NodeConnectionType.AiTool]);
.mockReturnValueOnce([NodeConnectionTypes.AiTool])
.mockReturnValueOnce([NodeConnectionTypes.AiTool]);
const { resolveNodePosition } = useCanvasOperations({ router });
const position = resolveNodePosition({ ...node, position: undefined }, nodeTypeDescription);
@@ -871,7 +871,7 @@ describe('useCanvasOperations', () => {
[
{
node: nodes[1].name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -882,7 +882,7 @@ describe('useCanvasOperations', () => {
[
{
node: nodes[2].name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -945,7 +945,7 @@ describe('useCanvasOperations', () => {
[
{
node: nodes[1].name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -958,7 +958,7 @@ describe('useCanvasOperations', () => {
[
{
node: nodes[2].name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -1172,8 +1172,8 @@ describe('useCanvasOperations', () => {
const nodeTypeName = SET_NODE_TYPE;
const nodeType = mockNodeTypeDescription({
name: nodeTypeName,
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
});
const nodes = [
mockNode({ id: 'a', name: 'Node A', type: nodeTypeName, position: [40, 40] }),
@@ -1186,17 +1186,17 @@ describe('useCanvasOperations', () => {
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
}),
target: nodes[1].id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
}),
data: {
source: { type: NodeConnectionType.Main, index: 0 },
target: { type: NodeConnectionType.Main, index: 0 },
source: { type: NodeConnectionTypes.Main, index: 0 },
target: { type: NodeConnectionTypes.Main, index: 0 },
},
},
{
@@ -1204,17 +1204,17 @@ describe('useCanvasOperations', () => {
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
}),
target: nodes[2].id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
}),
data: {
source: { type: NodeConnectionType.Main, index: 0 },
target: { type: NodeConnectionType.Main, index: 0 },
source: { type: NodeConnectionTypes.Main, index: 0 },
target: { type: NodeConnectionTypes.Main, index: 0 },
},
},
];
@@ -1237,12 +1237,12 @@ describe('useCanvasOperations', () => {
{
index: 0,
node: 'Node A',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
{
index: 0,
node: 'Node B',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
],
});
@@ -1307,8 +1307,8 @@ describe('useCanvasOperations', () => {
const nodeTypeDescription = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
});
const nodeA = createTestNode({
@@ -1325,9 +1325,9 @@ describe('useCanvasOperations', () => {
const connection: Connection = {
source: nodeA.id,
sourceHandle: `outputs/${NodeConnectionType.Main}/0`,
sourceHandle: `outputs/${NodeConnectionTypes.Main}/0`,
target: nodeB.id,
targetHandle: `inputs/${NodeConnectionType.Main}/0`,
targetHandle: `inputs/${NodeConnectionTypes.Main}/0`,
};
nodeTypesStore.nodeTypes = {
@@ -1350,8 +1350,8 @@ describe('useCanvasOperations', () => {
expect(workflowsStore.addConnection).toHaveBeenCalledWith({
connection: [
{ index: 0, node: nodeA.name, type: NodeConnectionType.Main },
{ index: 0, node: nodeB.name, type: NodeConnectionType.Main },
{ index: 0, node: nodeA.name, type: NodeConnectionTypes.Main },
{ index: 0, node: nodeB.name, type: NodeConnectionTypes.Main },
],
});
expect(uiStore.stateIsDirty).toBe(true);
@@ -1364,8 +1364,8 @@ describe('useCanvasOperations', () => {
const nodeTypeDescription = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
});
const nodeA = createTestNode({
@@ -1382,9 +1382,9 @@ describe('useCanvasOperations', () => {
const connection: Connection = {
source: nodeA.id,
sourceHandle: `outputs/${NodeConnectionType.Main}/0`,
sourceHandle: `outputs/${NodeConnectionTypes.Main}/0`,
target: nodeB.id,
targetHandle: `inputs/${NodeConnectionType.Main}/0`,
targetHandle: `inputs/${NodeConnectionTypes.Main}/0`,
};
nodeTypesStore.nodeTypes = {
@@ -1413,8 +1413,8 @@ describe('useCanvasOperations', () => {
it('deletes connection if both source and target nodes exist', () => {
const workflowsStore = mockedStore(useWorkflowsStore);
const connection: [IConnection, IConnection] = [
{ node: 'sourceNode', type: NodeConnectionType.Main, index: 0 },
{ node: 'targetNode', type: NodeConnectionType.Main, index: 0 },
{ node: 'sourceNode', type: NodeConnectionTypes.Main, index: 0 },
{ node: 'targetNode', type: NodeConnectionTypes.Main, index: 0 },
];
const testNode = createTestNode();
@@ -1443,7 +1443,7 @@ describe('useCanvasOperations', () => {
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
const targetNode = mockNode({
@@ -1457,7 +1457,7 @@ describe('useCanvasOperations', () => {
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1491,7 +1491,7 @@ describe('useCanvasOperations', () => {
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
const targetNode = mockNode({
@@ -1501,11 +1501,11 @@ describe('useCanvasOperations', () => {
});
const targetNodeTypeDescription = mockNodeTypeDescription({
name: targetNode.type,
inputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1533,11 +1533,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
};
@@ -1548,11 +1548,11 @@ describe('useCanvasOperations', () => {
});
const targetNodeTypeDescription = mockNodeTypeDescription({
name: 'targetType',
inputs: [NodeConnectionType.AiTool],
inputs: [NodeConnectionTypes.AiTool],
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
};
@@ -1584,11 +1584,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1599,11 +1599,11 @@ describe('useCanvasOperations', () => {
});
const targetNodeTypeDescription = mockNodeTypeDescription({
name: 'targetType',
inputs: [NodeConnectionType.AiTool],
inputs: [NodeConnectionTypes.AiTool],
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
};
@@ -1636,11 +1636,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1654,7 +1654,7 @@ describe('useCanvasOperations', () => {
name: 'targetType',
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
filter: {
nodes: ['allowedType'],
},
@@ -1663,7 +1663,7 @@ describe('useCanvasOperations', () => {
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1696,11 +1696,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
};
@@ -1714,7 +1714,7 @@ describe('useCanvasOperations', () => {
name: targetNode.type,
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
filter: {
nodes: [sourceNode.type],
},
@@ -1723,7 +1723,7 @@ describe('useCanvasOperations', () => {
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1756,11 +1756,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1774,7 +1774,7 @@ describe('useCanvasOperations', () => {
name: targetNode.type,
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
filter: {
nodes: [sourceNode.type],
},
@@ -1783,7 +1783,7 @@ describe('useCanvasOperations', () => {
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
};
@@ -1817,11 +1817,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1835,7 +1835,7 @@ describe('useCanvasOperations', () => {
name: targetNode.type,
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
filter: {
nodes: [sourceNode.type],
},
@@ -1844,7 +1844,7 @@ describe('useCanvasOperations', () => {
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1878,11 +1878,11 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1896,13 +1896,13 @@ describe('useCanvasOperations', () => {
name: targetNode.type,
inputs: [
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
],
});
const targetHandle: IConnection = {
node: targetNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -1936,16 +1936,16 @@ describe('useCanvasOperations', () => {
});
const sourceNodeTypeDescription = mockNodeTypeDescription({
name: sourceNode.type,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
const sourceHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
const targetHandle: IConnection = {
node: sourceNode.name,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
};
@@ -2012,9 +2012,9 @@ describe('useCanvasOperations', () => {
const connection: Connection = {
source: nodeA.id,
sourceHandle: `outputs/${NodeConnectionType.Main}/0`,
sourceHandle: `outputs/${NodeConnectionTypes.Main}/0`,
target: nodeB.id,
targetHandle: `inputs/${NodeConnectionType.Main}/0`,
targetHandle: `inputs/${NodeConnectionTypes.Main}/0`,
};
workflowsStore.getNodeById.mockReturnValueOnce(nodeA).mockReturnValueOnce(nodeB);
@@ -2024,8 +2024,8 @@ describe('useCanvasOperations', () => {
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
connection: [
{ index: 0, node: nodeA.name, type: NodeConnectionType.Main },
{ index: 0, node: nodeB.name, type: NodeConnectionType.Main },
{ index: 0, node: nodeA.name, type: NodeConnectionTypes.Main },
{ index: 0, node: nodeB.name, type: NodeConnectionTypes.Main },
],
});
});
@@ -2036,8 +2036,8 @@ describe('useCanvasOperations', () => {
const workflowsStore = mockedStore(useWorkflowsStore);
const connection: [IConnection, IConnection] = [
{ node: 'sourceNode', type: NodeConnectionType.Main, index: 1 },
{ node: 'targetNode', type: NodeConnectionType.Main, index: 2 },
{ node: 'sourceNode', type: NodeConnectionTypes.Main, index: 1 },
{ node: 'targetNode', type: NodeConnectionTypes.Main, index: 2 },
];
const { revertDeleteConnection } = useCanvasOperations({ router });
@@ -2088,7 +2088,7 @@ describe('useCanvasOperations', () => {
});
const targetNodeType = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
});
const sourceNodeId = 'source';
@@ -2099,14 +2099,14 @@ describe('useCanvasOperations', () => {
});
const sourceNodeType = mockNodeTypeDescription({
name: AGENT_NODE_TYPE,
outputs: [NodeConnectionType.AiTool],
outputs: [NodeConnectionTypes.AiTool],
});
workflowsStore.workflow.nodes = [sourceNode, targetNode];
workflowsStore.workflow.connections = {
[sourceNode.name]: {
[NodeConnectionType.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -2132,8 +2132,8 @@ describe('useCanvasOperations', () => {
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
connection: [
{ node: sourceNode.name, type: NodeConnectionType.AiTool, index: 0 },
{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 },
{ node: sourceNode.name, type: NodeConnectionTypes.AiTool, index: 0 },
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 },
],
});
});
@@ -2152,7 +2152,7 @@ describe('useCanvasOperations', () => {
});
const targetNodeType = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
});
const sourceNodeId = 'source';
@@ -2163,14 +2163,14 @@ describe('useCanvasOperations', () => {
});
const sourceNodeType = mockNodeTypeDescription({
name: AGENT_NODE_TYPE,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
workflowsStore.workflow.nodes = [sourceNode, targetNode];
workflowsStore.workflow.connections = {
[sourceNode.name]: {
[NodeConnectionType.Main]: [
[{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -2237,7 +2237,7 @@ describe('useCanvasOperations', () => {
});
const targetNodeType = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
});
const sourceNodeId = 'source';
@@ -2248,14 +2248,14 @@ describe('useCanvasOperations', () => {
});
const sourceNodeType = mockNodeTypeDescription({
name: AGENT_NODE_TYPE,
outputs: [NodeConnectionType.AiTool],
outputs: [NodeConnectionTypes.AiTool],
});
workflowsStore.workflow.nodes = [sourceNode, targetNode];
workflowsStore.workflow.connections = {
[sourceNode.name]: {
[NodeConnectionType.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -2281,8 +2281,8 @@ describe('useCanvasOperations', () => {
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
connection: [
{ node: sourceNode.name, type: NodeConnectionType.AiTool, index: 0 },
{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 },
{ node: sourceNode.name, type: NodeConnectionTypes.AiTool, index: 0 },
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 },
],
});
});
@@ -2301,7 +2301,7 @@ describe('useCanvasOperations', () => {
});
const targetNodeType = mockNodeTypeDescription({
name: SET_NODE_TYPE,
inputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
});
const sourceNodeId = 'source';
@@ -2312,14 +2312,14 @@ describe('useCanvasOperations', () => {
});
const sourceNodeType = mockNodeTypeDescription({
name: AGENT_NODE_TYPE,
outputs: [NodeConnectionType.Main],
outputs: [NodeConnectionTypes.Main],
});
workflowsStore.workflow.nodes = [sourceNode, targetNode];
workflowsStore.workflow.connections = {
[sourceNode.name]: {
[NodeConnectionType.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.AiTool]: [
[{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -2355,13 +2355,13 @@ describe('useCanvasOperations', () => {
workflowsStore.workflow.connections = {
[node1.name]: {
[NodeConnectionType.Main]: [
[{ node: node2.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: node2.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
node2: {
[NodeConnectionType.Main]: [
[{ node: node1.name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: node1.name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -2373,15 +2373,15 @@ describe('useCanvasOperations', () => {
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
connection: [
{ node: node1.name, type: NodeConnectionType.Main, index: 0 },
{ node: node2.name, type: NodeConnectionType.Main, index: 0 },
{ node: node1.name, type: NodeConnectionTypes.Main, index: 0 },
{ node: node2.name, type: NodeConnectionTypes.Main, index: 0 },
],
});
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
connection: [
{ node: node2.name, type: NodeConnectionType.Main, index: 0 },
{ node: node1.name, type: NodeConnectionType.Main, index: 0 },
{ node: node2.name, type: NodeConnectionTypes.Main, index: 0 },
{ node: node1.name, type: NodeConnectionTypes.Main, index: 0 },
],
});
@@ -2573,12 +2573,12 @@ describe('useCanvasOperations', () => {
describe('filterConnectionsByNodes', () => {
it('should return filtered connections when all nodes are included', () => {
const connections: INodeConnections = {
[NodeConnectionType.Main]: [
[NodeConnectionTypes.Main]: [
[
{ node: 'node1', type: NodeConnectionType.Main, index: 0 },
{ node: 'node2', type: NodeConnectionType.Main, index: 0 },
{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 },
{ node: 'node2', type: NodeConnectionTypes.Main, index: 0 },
],
[{ node: 'node3', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node3', type: NodeConnectionTypes.Main, index: 0 }],
],
};
const includeNodeNames = new Set<string>(['node1', 'node2', 'node3']);
@@ -2591,12 +2591,12 @@ describe('useCanvasOperations', () => {
it('should return empty connections when no nodes are included', () => {
const connections: INodeConnections = {
[NodeConnectionType.Main]: [
[NodeConnectionTypes.Main]: [
[
{ node: 'node1', type: NodeConnectionType.Main, index: 0 },
{ node: 'node2', type: NodeConnectionType.Main, index: 0 },
{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 },
{ node: 'node2', type: NodeConnectionTypes.Main, index: 0 },
],
[{ node: 'node3', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node3', type: NodeConnectionTypes.Main, index: 0 }],
],
};
const includeNodeNames = new Set<string>();
@@ -2605,18 +2605,18 @@ describe('useCanvasOperations', () => {
const result = filterConnectionsByNodes(connections, includeNodeNames);
expect(result).toEqual({
[NodeConnectionType.Main]: [[], []],
[NodeConnectionTypes.Main]: [[], []],
});
});
it('should return partially filtered connections when some nodes are included', () => {
const connections: INodeConnections = {
[NodeConnectionType.Main]: [
[NodeConnectionTypes.Main]: [
[
{ node: 'node1', type: NodeConnectionType.Main, index: 0 },
{ node: 'node2', type: NodeConnectionType.Main, index: 0 },
{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 },
{ node: 'node2', type: NodeConnectionTypes.Main, index: 0 },
],
[{ node: 'node3', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node3', type: NodeConnectionTypes.Main, index: 0 }],
],
};
const includeNodeNames = new Set<string>(['node1']);
@@ -2625,8 +2625,8 @@ describe('useCanvasOperations', () => {
const result = filterConnectionsByNodes(connections, includeNodeNames);
expect(result).toEqual({
[NodeConnectionType.Main]: [
[{ node: 'node1', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 }],
[],
],
});
@@ -2644,12 +2644,12 @@ describe('useCanvasOperations', () => {
it('should handle connections with no valid nodes', () => {
const connections: INodeConnections = {
[NodeConnectionType.Main]: [
[NodeConnectionTypes.Main]: [
[
{ node: 'node4', type: NodeConnectionType.Main, index: 0 },
{ node: 'node5', type: NodeConnectionType.Main, index: 0 },
{ node: 'node4', type: NodeConnectionTypes.Main, index: 0 },
{ node: 'node5', type: NodeConnectionTypes.Main, index: 0 },
],
[{ node: 'node6', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node6', type: NodeConnectionTypes.Main, index: 0 }],
],
};
const includeNodeNames = new Set<string>(['node1', 'node2', 'node3']);
@@ -2658,7 +2658,7 @@ describe('useCanvasOperations', () => {
const result = filterConnectionsByNodes(connections, includeNodeNames);
expect(result).toEqual({
[NodeConnectionType.Main]: [[], []],
[NodeConnectionTypes.Main]: [[], []],
});
});
});
@@ -2737,8 +2737,8 @@ describe('useCanvasOperations', () => {
const nodeTypeDescription = mockNodeTypeDescription({
name: nodeA.type,
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
});
nodeTypesStore.getNodeType = vi.fn(() => nodeTypeDescription);
@@ -2747,10 +2747,10 @@ describe('useCanvasOperations', () => {
workflowsStore.workflow.nodes = [nodeA, nodeB, nodeC];
workflowsStore.workflow.connections = {
[nodeA.name]: {
main: [[{ node: nodeB.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeB.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
[nodeB.name]: {
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
};
@@ -2774,10 +2774,10 @@ describe('useCanvasOperations', () => {
})[name],
);
workflowsStore.outgoingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 }]],
});
workflowsStore.incomingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeA.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeA.name, type: NodeConnectionTypes.Main, index: 0 }]],
});
const { connectAdjacentNodes } = useCanvasOperations({ router });
@@ -2786,8 +2786,8 @@ describe('useCanvasOperations', () => {
// Check that A was connected directly to C
expect(workflowsStore.addConnection).toHaveBeenCalledWith({
connection: [
{ node: nodeA.name, type: NodeConnectionType.Main, index: 0 },
{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 },
{ node: nodeA.name, type: NodeConnectionTypes.Main, index: 0 },
{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 },
],
});
@@ -2807,8 +2807,8 @@ describe('useCanvasOperations', () => {
const nodeTypeDescription = mockNodeTypeDescription({
name: nodeA.type,
inputs: [NodeConnectionType.Main, NodeConnectionType.Main],
outputs: [NodeConnectionType.Main, NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main, NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main, NodeConnectionTypes.Main],
});
nodeTypesStore.getNodeType = vi.fn(() => nodeTypeDescription);
@@ -2817,10 +2817,10 @@ describe('useCanvasOperations', () => {
workflowsStore.workflow.nodes = [nodeA, nodeB, nodeC];
workflowsStore.workflow.connections = {
[nodeA.name]: {
main: [[{ node: nodeB.name, type: NodeConnectionType.Main, index: 1 }]],
main: [[{ node: nodeB.name, type: NodeConnectionTypes.Main, index: 1 }]],
},
[nodeB.name]: {
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
};
@@ -2844,10 +2844,10 @@ describe('useCanvasOperations', () => {
})[name],
);
workflowsStore.outgoingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 1 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 1 }]],
});
workflowsStore.incomingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeA.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeA.name, type: NodeConnectionTypes.Main, index: 0 }]],
});
const { connectAdjacentNodes } = useCanvasOperations({ router });
@@ -2856,8 +2856,8 @@ describe('useCanvasOperations', () => {
// Check that A was connected directly to C
expect(workflowsStore.addConnection).toHaveBeenCalledWith({
connection: [
{ node: nodeA.name, type: NodeConnectionType.Main, index: 0 },
{ node: nodeC.name, type: NodeConnectionType.Main, index: 1 },
{ node: nodeA.name, type: NodeConnectionTypes.Main, index: 0 },
{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 1 },
],
});
@@ -2875,7 +2875,7 @@ describe('useCanvasOperations', () => {
workflowsStore.workflow.nodes = [nodeB, nodeC];
workflowsStore.workflow.connections = {
[nodeB.name]: {
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
};
@@ -2883,7 +2883,7 @@ describe('useCanvasOperations', () => {
workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject);
workflowsStore.getNodeById.mockReturnValue(nodeB);
workflowsStore.outgoingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeC.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeC.name, type: NodeConnectionTypes.Main, index: 0 }]],
});
workflowsStore.incomingConnectionsByNodeName.mockReturnValue({});
@@ -2903,7 +2903,7 @@ describe('useCanvasOperations', () => {
workflowsStore.workflow.nodes = [nodeA, nodeB];
workflowsStore.workflow.connections = {
[nodeA.name]: {
main: [[{ node: nodeB.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeB.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
};
@@ -2912,7 +2912,7 @@ describe('useCanvasOperations', () => {
workflowsStore.getNodeById.mockReturnValue(nodeB);
workflowsStore.outgoingConnectionsByNodeName.mockReturnValue({});
workflowsStore.incomingConnectionsByNodeName.mockReturnValue({
main: [[{ node: nodeA.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeA.name, type: NodeConnectionTypes.Main, index: 0 }]],
});
const { connectAdjacentNodes } = useCanvasOperations({ router });
@@ -2978,7 +2978,7 @@ describe('useCanvasOperations', () => {
nodes: [nodeA, nodeB],
connections: {
[nodeA.name]: {
main: [[{ node: nodeB.name, type: NodeConnectionType.Main, index: 0 }]],
main: [[{ node: nodeB.name, type: NodeConnectionTypes.Main, index: 0 }]],
},
},
};

View File

@@ -91,8 +91,9 @@ import type {
NodeInputConnections,
NodeParameterValueType,
Workflow,
NodeConnectionType,
} from 'n8n-workflow';
import { deepCopy, NodeConnectionType, NodeHelpers, TelemetryHelpers } from 'n8n-workflow';
import { deepCopy, NodeConnectionTypes, NodeHelpers, TelemetryHelpers } from 'n8n-workflow';
import { computed, nextTick, ref } from 'vue';
import type { useRouter } from 'vue-router';
import { useClipboard } from '@/composables/useClipboard';
@@ -724,13 +725,13 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
source: lastInteractedWithNodeId,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
target: node.id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
});
@@ -745,7 +746,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
source: node.id,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
target: lastInteractedWithNodeConnection.target,
@@ -899,7 +900,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
);
const nodeSize =
connectionType === NodeConnectionType.Main ? DEFAULT_NODE_SIZE : CONFIGURATION_NODE_SIZE;
connectionType === NodeConnectionTypes.Main ? DEFAULT_NODE_SIZE : CONFIGURATION_NODE_SIZE;
if (lastInteractedWithNode) {
const lastInteractedWithNodeTypeDescription = nodeTypesStore.getNodeType(
@@ -916,8 +917,8 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
// The new node should be placed at the same position as the mouse up event,
// designated by the `newNodeInsertPosition` value.
const xOffset = connectionType === NodeConnectionType.Main ? 0 : -nodeSize[0] / 2;
const yOffset = connectionType === NodeConnectionType.Main ? -nodeSize[1] / 2 : 0;
const xOffset = connectionType === NodeConnectionTypes.Main ? 0 : -nodeSize[0] / 2;
const yOffset = connectionType === NodeConnectionTypes.Main ? -nodeSize[1] / 2 : 0;
position = [newNodeInsertPosition[0] + xOffset, newNodeInsertPosition[1] + yOffset];
@@ -939,7 +940,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
const lastInteractedWithNodeScopedInputTypes = (
lastInteractedWithNodeInputTypes || []
).filter((input) => input !== NodeConnectionType.Main);
).filter((input) => input !== NodeConnectionTypes.Main);
const lastInteractedWithNodeOutputs = NodeHelpers.getNodeOutputs(
editableWorkflowObject.value,
@@ -951,7 +952,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
);
const lastInteractedWithNodeMainOutputs = lastInteractedWithNodeOutputTypes.filter(
(output) => output === NodeConnectionType.Main,
(output) => output === NodeConnectionTypes.Main,
);
let yOffset = 0;
@@ -994,7 +995,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
if (
outputTypes.length > 0 &&
outputTypes.every((outputName) => outputName !== NodeConnectionType.Main)
outputTypes.every((outputName) => outputName !== NodeConnectionTypes.Main)
) {
// When the added node has only non-main outputs (configuration nodes)
// We want to place the new node directly below the last interacted with node.
@@ -1021,7 +1022,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
let pushOffset = PUSH_NODES_OFFSET;
if (
!!lastInteractedWithNodeInputTypes.find((input) => input !== NodeConnectionType.Main)
!!lastInteractedWithNodeInputTypes.find((input) => input !== NodeConnectionTypes.Main)
) {
// If the node has scoped inputs, push it down a bit more
pushOffset += 140;

View File

@@ -6,7 +6,7 @@ import { createPinia, setActivePinia } from 'pinia';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
const nodeFactory = (data: Partial<INodeUi> = {}): INodeUi => ({
id: faker.string.uuid(),
@@ -97,8 +97,8 @@ describe('useContextMenu', () => {
const basicChain = nodeFactory({ type: BASIC_CHAIN_NODE_TYPE });
vi.spyOn(workflowsStore, 'getNodeById').mockReturnValue(basicChain);
vi.spyOn(NodeHelpers, 'getConnectionTypes').mockReturnValue([
NodeConnectionType.Main,
NodeConnectionType.AiLanguageModel,
NodeConnectionTypes.Main,
NodeConnectionTypes.AiLanguageModel,
]);
open(mockEvent, { source: 'node-right-click', nodeId: basicChain.id });

View File

@@ -4,7 +4,7 @@ import type { IExecutionResponse, INodeUi, Schema } from '@/Interface';
import { setActivePinia } from 'pinia';
import { createTestingPinia } from '@pinia/testing';
import {
NodeConnectionType,
NodeConnectionTypes,
type INodeExecutionData,
type ITaskDataConnections,
} from 'n8n-workflow';
@@ -560,7 +560,7 @@ describe('useDataSchema', () => {
});
const mockExecutionDataMarker = Symbol() as unknown as INodeExecutionData[];
const Main = NodeConnectionType.Main;
const Main = NodeConnectionTypes.Main;
test.each<
[

View File

@@ -12,7 +12,7 @@ import {
type INodeExecutionData,
type INodeTypeDescription,
type ITaskDataConnections,
NodeConnectionType,
NodeConnectionTypes,
} from 'n8n-workflow';
import { ref } from 'vue';
@@ -127,7 +127,7 @@ export function useDataSchema() {
outputIndex: number,
): INodeExecutionData[] {
if (
!connectionsData?.hasOwnProperty(NodeConnectionType.Main) ||
!connectionsData?.hasOwnProperty(NodeConnectionTypes.Main) ||
connectionsData.main === undefined ||
outputIndex < 0 ||
outputIndex >= connectionsData.main.length ||

View File

@@ -1,5 +1,5 @@
import { ref } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { useNodeConnections } from '@/composables/useNodeConnections';
import type { CanvasNodeData } from '@/types';
import { CanvasConnectionMode } from '@/types';
@@ -13,10 +13,10 @@ describe('useNodeConnections', () => {
describe('mainInputs', () => {
it('should return main inputs when provided with main inputs', () => {
const inputs = ref<CanvasNodeData['inputs']>([
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 1 },
{ type: NodeConnectionType.Main, index: 2 },
{ type: NodeConnectionType.AiAgent, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 1 },
{ type: NodeConnectionTypes.Main, index: 2 },
{ type: NodeConnectionTypes.AiAgent, index: 0 },
]);
const outputs = ref<CanvasNodeData['outputs']>([]);
@@ -34,9 +34,9 @@ describe('useNodeConnections', () => {
describe('nonMainInputs', () => {
it('should return non-main inputs when provided with non-main inputs', () => {
const inputs = ref<CanvasNodeData['inputs']>([
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.AiAgent, index: 0 },
{ type: NodeConnectionType.AiAgent, index: 1 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.AiAgent, index: 0 },
{ type: NodeConnectionTypes.AiAgent, index: 1 },
]);
const outputs = ref<CanvasNodeData['outputs']>([]);
@@ -54,9 +54,9 @@ describe('useNodeConnections', () => {
describe('requiredNonMainInputs', () => {
it('should return required non-main inputs when provided with required non-main inputs', () => {
const inputs = ref<CanvasNodeData['inputs']>([
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.AiAgent, required: true, index: 0 },
{ type: NodeConnectionType.AiAgent, required: false, index: 1 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.AiAgent, required: true, index: 0 },
{ type: NodeConnectionTypes.AiAgent, required: false, index: 1 },
]);
const outputs = ref<CanvasNodeData['outputs']>([]);
@@ -77,9 +77,9 @@ describe('useNodeConnections', () => {
const outputs = ref<CanvasNodeData['outputs']>([]);
const connections = ref<CanvasNodeData['connections']>({
[CanvasConnectionMode.Input]: {
[NodeConnectionType.Main]: [
[{ node: 'node1', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node2', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 }],
[{ node: 'node2', type: NodeConnectionTypes.Main, index: 0 }],
],
},
[CanvasConnectionMode.Output]: {},
@@ -93,7 +93,7 @@ describe('useNodeConnections', () => {
expect(mainInputConnections.value.length).toBe(2);
expect(mainInputConnections.value).toEqual(
connections.value[CanvasConnectionMode.Input][NodeConnectionType.Main],
connections.value[CanvasConnectionMode.Input][NodeConnectionTypes.Main],
);
});
});
@@ -102,10 +102,10 @@ describe('useNodeConnections', () => {
it('should return main outputs when provided with main outputs', () => {
const inputs = ref<CanvasNodeData['inputs']>([]);
const outputs = ref<CanvasNodeData['outputs']>([
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.Main, index: 1 },
{ type: NodeConnectionType.Main, index: 2 },
{ type: NodeConnectionType.AiAgent, index: 0 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.Main, index: 1 },
{ type: NodeConnectionTypes.Main, index: 2 },
{ type: NodeConnectionTypes.AiAgent, index: 0 },
]);
const { mainOutputs } = useNodeConnections({
@@ -123,9 +123,9 @@ describe('useNodeConnections', () => {
it('should return non-main outputs when provided with non-main outputs', () => {
const inputs = ref<CanvasNodeData['inputs']>([]);
const outputs = ref<CanvasNodeData['outputs']>([
{ type: NodeConnectionType.Main, index: 0 },
{ type: NodeConnectionType.AiAgent, index: 0 },
{ type: NodeConnectionType.AiAgent, index: 1 },
{ type: NodeConnectionTypes.Main, index: 0 },
{ type: NodeConnectionTypes.AiAgent, index: 0 },
{ type: NodeConnectionTypes.AiAgent, index: 1 },
]);
const { nonMainOutputs } = useNodeConnections({
@@ -146,9 +146,9 @@ describe('useNodeConnections', () => {
const connections = ref<CanvasNodeData['connections']>({
[CanvasConnectionMode.Input]: {},
[CanvasConnectionMode.Output]: {
[NodeConnectionType.Main]: [
[{ node: 'node1', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'node2', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'node1', type: NodeConnectionTypes.Main, index: 0 }],
[{ node: 'node2', type: NodeConnectionTypes.Main, index: 0 }],
],
},
});
@@ -161,7 +161,7 @@ describe('useNodeConnections', () => {
expect(mainOutputConnections.value.length).toBe(2);
expect(mainOutputConnections.value).toEqual(
connections.value[CanvasConnectionMode.Output][NodeConnectionType.Main],
connections.value[CanvasConnectionMode.Output][NodeConnectionTypes.Main],
);
});
});
@@ -182,12 +182,12 @@ describe('useNodeConnections', () => {
target: 'node1',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
};
@@ -200,12 +200,12 @@ describe('useNodeConnections', () => {
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
};
@@ -218,12 +218,12 @@ describe('useNodeConnections', () => {
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
index: 0,
}),
};
@@ -236,12 +236,12 @@ describe('useNodeConnections', () => {
target: 'node2',
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
}),
};

View File

@@ -2,7 +2,7 @@ import type { CanvasNodeData } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { MaybeRef } from 'vue';
import { computed, unref } from 'vue';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { Connection } from '@vue-flow/core';
import { parseCanvasConnectionHandleString } from '@/utils/canvasUtils';
@@ -20,11 +20,11 @@ export function useNodeConnections({
*/
const mainInputs = computed(() =>
unref(inputs).filter((input) => input.type === NodeConnectionType.Main),
unref(inputs).filter((input) => input.type === NodeConnectionTypes.Main),
);
const nonMainInputs = computed(() =>
unref(inputs).filter((input) => input.type !== NodeConnectionType.Main),
unref(inputs).filter((input) => input.type !== NodeConnectionTypes.Main),
);
const requiredNonMainInputs = computed(() =>
@@ -32,7 +32,7 @@ export function useNodeConnections({
);
const mainInputConnections = computed(
() => unref(connections)[CanvasConnectionMode.Input][NodeConnectionType.Main] ?? [],
() => unref(connections)[CanvasConnectionMode.Input][NodeConnectionTypes.Main] ?? [],
);
/**
@@ -40,15 +40,15 @@ export function useNodeConnections({
*/
const mainOutputs = computed(() =>
unref(outputs).filter((output) => output.type === NodeConnectionType.Main),
unref(outputs).filter((output) => output.type === NodeConnectionTypes.Main),
);
const nonMainOutputs = computed(() =>
unref(outputs).filter((output) => output.type !== NodeConnectionType.Main),
unref(outputs).filter((output) => output.type !== NodeConnectionTypes.Main),
);
const mainOutputConnections = computed(
() => unref(connections)[CanvasConnectionMode.Output][NodeConnectionType.Main] ?? [],
() => unref(connections)[CanvasConnectionMode.Output][NodeConnectionTypes.Main] ?? [],
);
/**

View File

@@ -13,7 +13,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { CanvasNodeDirtiness } from '@/types';
import { type FrontendSettings } from '@n8n/api-types';
import { createTestingPinia } from '@pinia/testing';
import { NodeConnectionType, type IConnections, type IRunData } from 'n8n-workflow';
import { NodeConnectionTypes, type IConnections, type IRunData } from 'n8n-workflow';
import { defineComponent } from 'vue';
import {
createRouter,
@@ -396,8 +396,8 @@ describe(useNodeDirtiness, () => {
const from = arr[i - 1].slice(0, 1);
const to = arr[i + 1].slice(0, 1);
const type = arr[i - 1].includes('🧠')
? NodeConnectionType.AiAgent
: NodeConnectionType.Main;
? NodeConnectionTypes.AiAgent
: NodeConnectionTypes.Main;
const conns = connections[from]?.[type] ?? [];
const conn = conns[0] ?? [];

View File

@@ -11,7 +11,8 @@ import { useHistoryStore } from '@/stores/history.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { CanvasNodeDirtiness, type CanvasNodeDirtinessType } from '@/types';
import { type INodeConnections, NodeConnectionType } from 'n8n-workflow';
import type { INodeConnections, NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { computed } from 'vue';
/**
@@ -68,7 +69,7 @@ function shouldCommandMarkDirty(
incomingNodes.includes(command.nodeName) &&
(command.newState ||
Object.keys(getOutgoingConnectors(command.nodeName)).some(
(type) => (type as NodeConnectionType) !== NodeConnectionType.Main,
(type) => (type as NodeConnectionType) !== NodeConnectionTypes.Main,
))
);
}
@@ -93,7 +94,7 @@ function findLoop(
const newVisited = [...visited, nodeName];
for (const [type, typeConnections] of Object.entries(getIncomingConnections(nodeName))) {
if ((type as NodeConnectionType) !== NodeConnectionType.Main) {
if ((type as NodeConnectionType) !== NodeConnectionTypes.Main) {
continue;
}
@@ -121,7 +122,7 @@ export function useNodeDirtiness() {
function getParentSubNodes(nodeName: string) {
return Object.entries(workflowsStore.incomingConnectionsByNodeName(nodeName))
.filter(([type]) => (type as NodeConnectionType) !== NodeConnectionType.Main)
.filter(([type]) => (type as NodeConnectionType) !== NodeConnectionTypes.Main)
.flatMap(([, typeConnections]) => typeConnections.flat().filter((conn) => conn !== null));
}
@@ -193,7 +194,7 @@ export function useNodeDirtiness() {
for (const [type, typeConnections] of Object.entries(
workflowsStore.outgoingConnectionsByNodeName(nodeName),
)) {
if ((type as NodeConnectionType) !== NodeConnectionType.Main) {
if ((type as NodeConnectionType) !== NodeConnectionTypes.Main) {
continue;
}

View File

@@ -6,7 +6,7 @@ import {
SPLIT_IN_BATCHES_NODE_TYPE,
} from '@/constants';
import { NodeHelpers, ExpressionEvaluatorProxy, NodeConnectionType } from 'n8n-workflow';
import { NodeHelpers, ExpressionEvaluatorProxy, NodeConnectionTypes } from 'n8n-workflow';
import type {
INodeProperties,
INodeCredentialDescription,
@@ -27,6 +27,7 @@ import type {
INodeParameters,
INodeTypeNameVersion,
NodeParameterValue,
NodeConnectionType,
} from 'n8n-workflow';
import type {
@@ -560,7 +561,7 @@ export function useNodeHelpers() {
runIndex = 0,
outputIndex = 0,
paneType: NodePanelType = 'output',
connectionType: NodeConnectionType = NodeConnectionType.Main,
connectionType: NodeConnectionType = NodeConnectionTypes.Main,
): INodeExecutionData[] {
//TODO: check if this needs to be fixed in different place
if (
@@ -592,7 +593,7 @@ export function useNodeHelpers() {
function getInputData(
connectionsData: ITaskDataConnections,
outputIndex: number,
connectionType: NodeConnectionType = NodeConnectionType.Main,
connectionType: NodeConnectionType = NodeConnectionTypes.Main,
): INodeExecutionData[] {
return connectionsData?.[connectionType]?.[outputIndex] ?? [];
}
@@ -602,7 +603,7 @@ export function useNodeHelpers() {
node: string | null,
runIndex: number,
outputIndex: number,
connectionType: NodeConnectionType = NodeConnectionType.Main,
connectionType: NodeConnectionType = NodeConnectionTypes.Main,
): IBinaryKeyData[] {
if (node === null) {
return [];

View File

@@ -6,7 +6,8 @@ import type { INodeUi } from '@/Interface';
import { HTTP_REQUEST_NODE_TYPE, IF_NODE_TYPE, MAX_PINNED_DATA_SIZE } from '@/constants';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useTelemetry } from '@/composables/useTelemetry';
import { NodeConnectionType, STICKY_NODE_TYPE, type INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionTypes, STICKY_NODE_TYPE } from 'n8n-workflow';
import type { NodeConnectionType, INodeTypeDescription } from 'n8n-workflow';
vi.mock('@/composables/useToast', () => ({ useToast: vi.fn(() => ({ showError: vi.fn() })) }));
vi.mock('@/composables/useI18n', () => ({
@@ -156,7 +157,7 @@ describe('usePinnedData', () => {
parameters: {},
onError: 'stopWorkflow',
} as INodeUi);
getNodeType.mockReturnValue(makeNodeType([NodeConnectionType.Main], HTTP_REQUEST_NODE_TYPE));
getNodeType.mockReturnValue(makeNodeType([NodeConnectionTypes.Main], HTTP_REQUEST_NODE_TYPE));
const { canPinNode } = usePinnedData(node);
@@ -175,7 +176,7 @@ describe('usePinnedData', () => {
parameters: {},
onError: 'continueErrorOutput',
} as INodeUi);
getNodeType.mockReturnValue(makeNodeType([NodeConnectionType.Main], HTTP_REQUEST_NODE_TYPE));
getNodeType.mockReturnValue(makeNodeType([NodeConnectionTypes.Main], HTTP_REQUEST_NODE_TYPE));
const { canPinNode } = usePinnedData(node);
@@ -196,7 +197,7 @@ describe('usePinnedData', () => {
onError: 'stopWorkflow',
} as INodeUi);
getNodeType.mockReturnValue(
makeNodeType([NodeConnectionType.Main, NodeConnectionType.Main], IF_NODE_TYPE),
makeNodeType([NodeConnectionTypes.Main, NodeConnectionTypes.Main], IF_NODE_TYPE),
);
const { canPinNode } = usePinnedData(node);
@@ -227,7 +228,7 @@ describe('usePinnedData', () => {
typeVersion: 1,
type: HTTP_REQUEST_NODE_TYPE,
} as INodeUi);
getNodeType.mockReturnValue(makeNodeType([NodeConnectionType.Main], HTTP_REQUEST_NODE_TYPE));
getNodeType.mockReturnValue(makeNodeType([NodeConnectionTypes.Main], HTTP_REQUEST_NODE_TYPE));
const { canPinNode } = usePinnedData(node);

View File

@@ -1,7 +1,7 @@
import { useToast } from '@/composables/useToast';
import { useI18n } from '@/composables/useI18n';
import type { INodeExecutionData, IPinData } from 'n8n-workflow';
import { jsonParse, jsonStringify, NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { jsonParse, jsonStringify, NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
import {
MAX_EXPECTED_REQUEST_SIZE,
MAX_PINNED_DATA_SIZE,
@@ -90,7 +90,7 @@ export function usePinnedData(
);
const mainOutputs = outputs.filter(
(output) => output.type === NodeConnectionType.Main && output.category !== 'error',
(output) => output.type === NodeConnectionTypes.Main && output.category !== 'error',
);
let indexAcceptable = true;
@@ -100,7 +100,7 @@ export function usePinnedData(
if (outputs[outputIndex] === undefined) return false;
indexAcceptable = output.type === NodeConnectionType.Main && output.category !== 'error';
indexAcceptable = output.type === NodeConnectionTypes.Main && output.category !== 'error';
}
return mainOutputs.length === 1 && indexAcceptable;

View File

@@ -9,7 +9,7 @@ import {
type Workflow,
type IExecuteData,
type ITaskData,
NodeConnectionType,
NodeConnectionTypes,
type INodeConnections,
} from 'n8n-workflow';
@@ -340,12 +340,12 @@ describe('useRunWorkflow({ router })', () => {
];
vi.mocked(workflowsStore).outgoingConnectionsByNodeName.mockImplementation((nodeName) =>
nodeName === parentName
? { main: [[{ node: executeName, type: NodeConnectionType.Main, index: 0 }]] }
? { main: [[{ node: executeName, type: NodeConnectionTypes.Main, index: 0 }]] }
: ({} as INodeConnections),
);
vi.mocked(workflowsStore).incomingConnectionsByNodeName.mockImplementation((nodeName) =>
nodeName === executeName
? { main: [[{ node: parentName, type: NodeConnectionType.Main, index: 0 }]] }
? { main: [[{ node: parentName, type: NodeConnectionTypes.Main, index: 0 }]] }
: ({} as INodeConnections),
);
vi.mocked(workflowsStore).getWorkflowRunData = {

View File

@@ -18,7 +18,7 @@ import type {
IWorkflowBase,
} from 'n8n-workflow';
import { NodeConnectionType, TelemetryHelpers } from 'n8n-workflow';
import { NodeConnectionTypes, TelemetryHelpers } from 'n8n-workflow';
import { useToast } from '@/composables/useToast';
import { useNodeHelpers } from '@/composables/useNodeHelpers';
@@ -114,7 +114,7 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
if (options.destinationNode !== undefined) {
directParentNodes = workflow.getParentNodes(
options.destinationNode,
NodeConnectionType.Main,
NodeConnectionTypes.Main,
-1,
);
}
@@ -151,7 +151,7 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
startNodeNames.push(options.destinationNode);
} else if (options.triggerNode && options.nodeData) {
startNodeNames.push(
...workflow.getChildNodes(options.triggerNode, NodeConnectionType.Main, 1),
...workflow.getChildNodes(options.triggerNode, NodeConnectionTypes.Main, 1),
);
newRunData = { [options.triggerNode]: [options.nodeData] };
executedNode = options.triggerNode;
@@ -222,14 +222,14 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
// Find for each start node the source data
let sourceData = get(runData, [name, 0, 'source', 0], null);
if (sourceData === null) {
const parentNodes = workflow.getParentNodes(name, NodeConnectionType.Main, 1);
const parentNodes = workflow.getParentNodes(name, NodeConnectionTypes.Main, 1);
const executeData = workflowHelpers.executeData(
parentNodes,
name,
NodeConnectionType.Main,
NodeConnectionTypes.Main,
0,
);
sourceData = get(executeData, ['source', NodeConnectionType.Main, 0], null);
sourceData = get(executeData, ['source', NodeConnectionTypes.Main, 0], null);
}
return {
name,
@@ -373,7 +373,7 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
for (const directParentNode of directParentNodes) {
// Go over the parents of that node so that we can get a start
// node for each of the branches
const parentNodes = workflow.getParentNodes(directParentNode, NodeConnectionType.Main);
const parentNodes = workflow.getParentNodes(directParentNode, NodeConnectionTypes.Main);
// Add also the enabled direct parent to be checked
if (workflow.nodes[directParentNode].disabled) continue;

View File

@@ -25,7 +25,7 @@ import type {
NodeParameterValue,
Workflow,
} from 'n8n-workflow';
import { NodeConnectionType, ExpressionEvaluatorProxy, NodeHelpers } from 'n8n-workflow';
import { NodeConnectionTypes, ExpressionEvaluatorProxy, NodeHelpers } from 'n8n-workflow';
import type {
ICredentialsResponse,
@@ -123,7 +123,7 @@ export function resolveParameter<T = IDataObject>(
) as T;
}
const inputName = NodeConnectionType.Main;
const inputName = NodeConnectionTypes.Main;
const activeNode =
useNDVStore().activeNode ?? useWorkflowsStore().getNodeByName(opts.contextNodeName || '');
@@ -416,7 +416,7 @@ export function executeData(
].main) {
for (const connection of mainConnections ?? []) {
if (
connection.type === NodeConnectionType.Main &&
connection.type === NodeConnectionTypes.Main &&
connection.node === parentNodeName
) {
previousNodeOutput = connection.index;

View File

@@ -3,7 +3,8 @@ import type {
EnterpriseEditionFeatureValue,
NodeCreatorOpenSource,
} from './Interface';
import { NodeConnectionType } from 'n8n-workflow';
import type { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type {
CanvasInjectionData,
CanvasNodeHandleInjectionData,
@@ -301,9 +302,8 @@ export const REQUEST_NODE_FORM_URL = 'https://n8n-community.typeform.com/to/K1fB
// Node Connection Types
export const NODE_CONNECTION_TYPE_ALLOW_MULTIPLE: NodeConnectionType[] = [
NodeConnectionType.AiTool,
NodeConnectionType.Main,
NodeConnectionTypes.AiTool,
NodeConnectionTypes.Main,
];
// General

View File

@@ -1,4 +1,4 @@
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { INodeUi, IWorkflowDataCreate } from './Interface';
export const SAMPLE_SUBWORKFLOW_WORKFLOW: IWorkflowDataCreate = {
@@ -26,7 +26,7 @@ export const SAMPLE_SUBWORKFLOW_WORKFLOW: IWorkflowDataCreate = {
[
{
node: 'Replace me with your logic',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -143,7 +143,7 @@ export const SAMPLE_EVALUATION_WORKFLOW: IWorkflowDataCreate = {
[
{
node: 'Replace me',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -154,7 +154,7 @@ export const SAMPLE_EVALUATION_WORKFLOW: IWorkflowDataCreate = {
[
{
node: 'Return metric(s)',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],

View File

@@ -5,7 +5,7 @@ import { CompletionContext, insertCompletionText } from '@codemirror/autocomplet
import { javascriptLanguage } from '@codemirror/lang-javascript';
import { EditorState } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { NodeConnectionType, type IConnections } from 'n8n-workflow';
import { NodeConnectionTypes, type IConnections } from 'n8n-workflow';
import type { MockInstance } from 'vitest';
import { autocompletableNodeNames, expressionWithFirstItem, stripExcessParens } from './utils';
@@ -83,13 +83,13 @@ describe('completion utils', () => {
];
const connections = {
[nodes[0].name]: {
[NodeConnectionType.Main]: [
[{ node: nodes[1].name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: nodes[1].name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
[nodes[1].name]: {
[NodeConnectionType.Main]: [
[{ node: nodes[2].name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: nodes[2].name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -116,13 +116,13 @@ describe('completion utils', () => {
];
const connections: IConnections = {
[nodes[0].name]: {
[NodeConnectionType.Main]: [
[{ node: nodes[1].name, type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: nodes[1].name, type: NodeConnectionTypes.Main, index: 0 }],
],
},
[nodes[2].name]: {
[NodeConnectionType.AiMemory]: [
[{ node: nodes[1].name, type: NodeConnectionType.AiMemory, index: 0 }],
[NodeConnectionTypes.AiMemory]: [
[{ node: nodes[1].name, type: NodeConnectionTypes.AiMemory, index: 0 }],
],
},
};

View File

@@ -13,7 +13,7 @@ import { LanguageSupport } from '@codemirror/language';
import { Text, type Extension } from '@codemirror/state';
import { EditorView, hoverTooltip } from '@codemirror/view';
import * as Comlink from 'comlink';
import { NodeConnectionType, type CodeExecutionMode, type INodeExecutionData } from 'n8n-workflow';
import { NodeConnectionTypes, type CodeExecutionMode, type INodeExecutionData } from 'n8n-workflow';
import { onBeforeUnmount, ref, toRef, toValue, watch, type MaybeRefOrGetter } from 'vue';
import type { LanguageServiceWorker, RemoteLanguageServiceWorkerInit } from '../types';
import { typescriptCompletionSource } from './completions';
@@ -49,7 +49,7 @@ export function useTypescript(
inputNodeNames: activeNodeName
? workflowsStore
.getCurrentWorkflow()
.getParentNodes(activeNodeName, NodeConnectionType.Main, 1)
.getParentNodes(activeNodeName, NodeConnectionTypes.Main, 1)
: [],
mode: toValue(mode),
},

View File

@@ -20,7 +20,7 @@ import {
STORES,
} from '@/constants';
import type { INodeIssues } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { defineStore } from 'pinia';
import { v4 as uuid } from 'uuid';
import { useWorkflowsStore } from './workflows.store';
@@ -181,7 +181,7 @@ export const useNDVStore = defineStore(STORES.NDV, () => {
return false;
}
const workflow = workflowsStore.getCurrentWorkflow();
const parentNodes = workflow.getParentNodes(activeNode.value.name, NodeConnectionType.Main, 1);
const parentNodes = workflow.getParentNodes(activeNode.value.name, NodeConnectionTypes.Main, 1);
return parentNodes.includes(inputNodeName);
});
@@ -269,7 +269,11 @@ export const useNDVStore = defineStore(STORES.NDV, () => {
type,
data,
dimensions,
}: { type: string; data: string; dimensions: DOMRect | null }): void => {
}: {
type: string;
data: string;
dimensions: DOMRect | null;
}): void => {
draggable.value = {
isDragging: true,
type,
@@ -314,10 +318,7 @@ export const useNDVStore = defineStore(STORES.NDV, () => {
}
};
const setNDVPanelDataIsEmpty = (params: {
panel: NodePanelType;
isEmpty: boolean;
}): void => {
const setNDVPanelDataIsEmpty = (params: { panel: NodePanelType; isEmpty: boolean }): void => {
if (params.panel === 'input') {
input.value.data.isEmpty = params.isEmpty;
} else {

View File

@@ -8,7 +8,7 @@ import {
} from '@/constants';
import type { INodeCreateElement } from '@/Interface';
import { parseCanvasConnectionHandleString } from '@/utils/canvasUtils';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import { CanvasConnectionMode } from '@/types';
const workflow_id = 'workflow-id';
@@ -333,7 +333,7 @@ describe('useNodeCreatorStore', () => {
it('sets nodeCreatorView to AI_UNCATEGORIZED_CATEGORY when connection type is not Main', async () => {
mockedParseCanvasConnectionHandleString.mockReturnValue({
type: NodeConnectionType.AiLanguageModel, // any value that is not NodeConnectionType.Main
type: NodeConnectionTypes.AiLanguageModel, // any value that is not NodeConnectionTypes.Main
index: 0,
mode: CanvasConnectionMode.Input,
});
@@ -354,7 +354,7 @@ describe('useNodeCreatorStore', () => {
it('uses the provided nodeCreatorView when connection type is Main', async () => {
mockedParseCanvasConnectionHandleString.mockReturnValue({
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
mode: CanvasConnectionMode.Input,
});

View File

@@ -20,8 +20,13 @@ import type {
import { computed, ref } from 'vue';
import { transformNodeType } from '@/components/Node/NodeCreator/utils';
import type { IDataObject, INodeInputConfiguration, NodeParameterValueType } from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import type {
IDataObject,
INodeInputConfiguration,
NodeParameterValueType,
NodeConnectionType,
} from 'n8n-workflow';
import { NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useUIStore } from '@/stores/ui.store';
import { useNDVStore } from '@/stores/ndv.store';
@@ -181,7 +186,7 @@ export const useNodeCreatorStore = defineStore(STORES.NODE_CREATOR, () => {
uiStore.lastInteractedWithNodeId = sourceNode.id;
const isOutput = mode === CanvasConnectionMode.Output;
const isScopedConnection = type !== NodeConnectionType.Main;
const isScopedConnection = type !== NodeConnectionTypes.Main;
setNodeCreatorState({
source: eventSource,
createNodeActive: true,

View File

@@ -16,8 +16,9 @@ import type {
INodeTypeDescription,
INodeTypeNameVersion,
Workflow,
NodeConnectionType,
} from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { NodeConnectionTypes, NodeHelpers } from 'n8n-workflow';
import { defineStore } from 'pinia';
import { useCredentialsStore } from './credentials.store';
import { useRootStore } from './root.store';
@@ -109,7 +110,7 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
return outputTypes
? outputTypes.filter((output) => output !== NodeConnectionType.Main).length > 0
? outputTypes.filter((output) => output !== NodeConnectionTypes.Main).length > 0
: false;
};
});
@@ -154,15 +155,15 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
// If outputs is not an array, it must be a string expression
// in which case we'll try to match all possible non-main output types that are supported
const connectorTypes: NodeConnectionType[] = [
NodeConnectionType.AiVectorStore,
NodeConnectionType.AiChain,
NodeConnectionType.AiDocument,
NodeConnectionType.AiEmbedding,
NodeConnectionType.AiLanguageModel,
NodeConnectionType.AiMemory,
NodeConnectionType.AiOutputParser,
NodeConnectionType.AiTextSplitter,
NodeConnectionType.AiTool,
NodeConnectionTypes.AiVectorStore,
NodeConnectionTypes.AiChain,
NodeConnectionTypes.AiDocument,
NodeConnectionTypes.AiEmbedding,
NodeConnectionTypes.AiLanguageModel,
NodeConnectionTypes.AiMemory,
NodeConnectionTypes.AiOutputParser,
NodeConnectionTypes.AiTextSplitter,
NodeConnectionTypes.AiTool,
];
connectorTypes.forEach((outputType: NodeConnectionType) => {
if (outputTypes.includes(outputType)) {
@@ -214,7 +215,7 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
return inputTypes
? inputTypes.filter((input) => input !== NodeConnectionType.Main).length > 0
? inputTypes.filter((input) => input !== NodeConnectionTypes.Main).length > 0
: false;
};
});

View File

@@ -57,7 +57,7 @@ import type {
} from 'n8n-workflow';
import {
deepCopy,
NodeConnectionType,
NodeConnectionTypes,
NodeHelpers,
SEND_AND_WAIT_OPERATION,
Workflow,
@@ -1624,7 +1624,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
function checkIfNodeHasChatParent(nodeName: string): boolean {
const workflow = getCurrentWorkflow();
const parents = workflow.getParentNodes(nodeName, NodeConnectionType.Main);
const parents = workflow.getParentNodes(nodeName, NodeConnectionTypes.Main);
const matchedChatNode = parents.find((parent) => {
const parentNodeType = getNodeByName(parent)?.type;

View File

@@ -9,7 +9,7 @@ import {
parseCanvasConnectionHandleString,
} from '@/utils/canvasUtils';
import type { IConnection, IConnections, INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { CanvasConnection } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { INodeUi } from '@/Interface';
@@ -24,7 +24,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should map legacy connections to canvas connections', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
[NodeConnectionTypes.Main]: [
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
const nodes: INodeUi[] = [
@@ -54,13 +56,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const source = nodes[0].id;
const sourceHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const target = nodes[1].id;
const targetHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const id = createCanvasConnectionId({
@@ -81,12 +83,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -96,7 +98,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should return empty array when no matching nodes found', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
[NodeConnectionTypes.Main]: [
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
const nodes: INodeUi[] = [];
@@ -141,9 +145,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should map multiple connections between the same nodes', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'Node B', type: NodeConnectionType.Main, index: 1 }],
[NodeConnectionTypes.Main]: [
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 1 }],
],
},
};
@@ -174,13 +178,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceA = nodes[0].id;
const sourceHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const targetA = nodes[1].id;
const targetHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const connectionIdA = createCanvasConnectionId({
@@ -193,13 +197,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceB = nodes[0].id;
const sourceHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
});
const targetB = nodes[1].id;
const targetHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
});
const connectionIdB = createCanvasConnectionId({
@@ -220,12 +224,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -239,12 +243,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 1,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 1,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -254,9 +258,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should map multiple connections from one node to different nodes', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'Node C', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
[{ node: 'Node C', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -295,13 +299,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceA = nodes[0].id;
const sourceHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const targetA = nodes[1].id;
const targetHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const connectionIdA = createCanvasConnectionId({
@@ -314,13 +318,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceB = nodes[0].id;
const sourceHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
});
const targetB = nodes[2].id;
const targetHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const connectionIdB = createCanvasConnectionId({
@@ -341,12 +345,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -360,12 +364,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 1,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[2].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -375,13 +379,17 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should map complex node setup with mixed inputs and outputs', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
[NodeConnectionType.AiMemory]: [
[{ node: 'Node C', type: NodeConnectionType.AiMemory, index: 1 }],
[NodeConnectionTypes.Main]: [
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
],
[NodeConnectionTypes.AiMemory]: [
[{ node: 'Node C', type: NodeConnectionTypes.AiMemory, index: 1 }],
],
},
'Node B': {
[NodeConnectionType.Main]: [[{ node: 'Node C', type: NodeConnectionType.Main, index: 0 }]],
[NodeConnectionTypes.Main]: [
[{ node: 'Node C', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
const nodes: INodeUi[] = [
@@ -419,13 +427,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceA = nodes[0].id;
const sourceHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const targetA = nodes[1].id;
const targetHandleA = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const connectionIdA = createCanvasConnectionId({
@@ -438,13 +446,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceB = nodes[0].id;
const sourceHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
index: 0,
});
const targetB = nodes[2].id;
const targetHandleB = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
index: 1,
});
const connectionIdB = createCanvasConnectionId({
@@ -457,13 +465,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const sourceC = nodes[1].id;
const sourceHandleC = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const targetC = nodes[2].id;
const targetHandleC = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const connectionIdC = createCanvasConnectionId({
@@ -484,12 +492,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -503,12 +511,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 0,
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
},
target: {
node: nodes[2].name,
index: 1,
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
},
},
},
@@ -522,12 +530,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[2].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -537,9 +545,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should handle edge cases with invalid data gracefully', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [
[{ node: 'Nonexistent Node', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
[NodeConnectionTypes.Main]: [
[{ node: 'Nonexistent Node', type: NodeConnectionTypes.Main, index: 0 }],
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -570,14 +578,14 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const source = nodes[0].id;
const sourceHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
});
const target = nodes[1].id;
const targetHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
@@ -599,12 +607,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 1,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -615,9 +623,9 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
it('should handle null connections gracefully', () => {
const legacyConnections: IConnections = {
'Node A': {
[NodeConnectionType.Main]: [
[NodeConnectionTypes.Main]: [
null as unknown as IConnection[],
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
[{ node: 'Node B', type: NodeConnectionTypes.Main, index: 0 }],
],
},
};
@@ -648,13 +656,13 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
const source = nodes[0].id;
const sourceHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 1,
});
const target = nodes[1].id;
const targetHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
});
const id = createCanvasConnectionId({
@@ -675,12 +683,12 @@ describe('mapLegacyConnectionsToCanvasConnections', () => {
source: {
node: nodes[0].name,
index: 1,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
target: {
node: nodes[1].name,
index: 0,
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
},
},
},
@@ -754,18 +762,18 @@ describe('createCanvasConnectionHandleString', () => {
it('should create handle string with provided values', () => {
const result = createCanvasConnectionHandleString({
mode: 'outputs',
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
index: 2,
});
expect(result).toBe(`outputs/${NodeConnectionType.AiMemory}/2`);
expect(result).toBe(`outputs/${NodeConnectionTypes.AiMemory}/2`);
});
it('should create handle string with mode and type only', () => {
const result = createCanvasConnectionHandleString({
mode: 'inputs',
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
});
expect(result).toBe(`inputs/${NodeConnectionType.AiTool}/0`);
expect(result).toBe(`inputs/${NodeConnectionTypes.AiTool}/0`);
});
it('should create handle string with mode and index only', () => {
@@ -811,15 +819,15 @@ describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
it('should map string endpoints correctly', () => {
const endpoints: INodeTypeDescription['inputs'] = [
NodeConnectionType.Main,
NodeConnectionType.AiTool,
NodeConnectionTypes.Main,
NodeConnectionTypes.AiTool,
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: undefined },
{ type: NodeConnectionTypes.Main, index: 0, label: undefined },
{
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
label: undefined,
maxConnections: undefined,
@@ -829,15 +837,15 @@ describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
it('should map object endpoints correctly', () => {
const endpoints: INodeTypeDescription['inputs'] = [
{ type: NodeConnectionType.Main, displayName: 'Main Input' },
{ type: NodeConnectionType.AiTool, displayName: 'AI Tool', required: true },
{ type: NodeConnectionTypes.Main, displayName: 'Main Input' },
{ type: NodeConnectionTypes.AiTool, displayName: 'AI Tool', required: true },
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input' },
{ type: NodeConnectionTypes.Main, index: 0, label: 'Main Input' },
{
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
label: 'AI Tool',
required: true,
@@ -848,61 +856,61 @@ describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
it('should map mixed string and object endpoints correctly', () => {
const endpoints: INodeTypeDescription['inputs'] = [
NodeConnectionType.Main,
{ type: NodeConnectionType.AiTool, displayName: 'AI Tool' },
NodeConnectionType.Main,
NodeConnectionTypes.Main,
{ type: NodeConnectionTypes.AiTool, displayName: 'AI Tool' },
NodeConnectionTypes.Main,
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: undefined },
{ type: NodeConnectionTypes.Main, index: 0, label: undefined },
{
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
label: 'AI Tool',
maxConnections: undefined,
},
{ type: NodeConnectionType.Main, index: 1, label: undefined },
{ type: NodeConnectionTypes.Main, index: 1, label: undefined },
]);
});
it('should handle multiple same type object endpoints', () => {
const endpoints: INodeTypeDescription['inputs'] = [
{ type: NodeConnectionType.Main, displayName: 'Main Input' },
{ type: NodeConnectionType.Main, displayName: 'Secondary Main Input' },
{ type: NodeConnectionTypes.Main, displayName: 'Main Input' },
{ type: NodeConnectionTypes.Main, displayName: 'Secondary Main Input' },
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input' },
{ type: NodeConnectionType.Main, index: 1, label: 'Secondary Main Input' },
{ type: NodeConnectionTypes.Main, index: 0, label: 'Main Input' },
{ type: NodeConnectionTypes.Main, index: 1, label: 'Secondary Main Input' },
]);
});
it('should handle endpoints with separate names', () => {
const endpoints: INodeTypeDescription['inputs'] = [
NodeConnectionType.Main,
NodeConnectionType.Main,
NodeConnectionTypes.Main,
NodeConnectionTypes.Main,
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints, ['First', 'Second']);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: 'First' },
{ type: NodeConnectionType.Main, index: 1, label: 'Second' },
{ type: NodeConnectionTypes.Main, index: 0, label: 'First' },
{ type: NodeConnectionTypes.Main, index: 1, label: 'Second' },
]);
});
it('should map required and non-required endpoints correctly', () => {
const endpoints: INodeTypeDescription['inputs'] = [
{ type: NodeConnectionType.Main, displayName: 'Main Input', required: true },
{ type: NodeConnectionType.AiTool, displayName: 'Optional Tool', required: false },
{ type: NodeConnectionTypes.Main, displayName: 'Main Input', required: true },
{ type: NodeConnectionTypes.AiTool, displayName: 'Optional Tool', required: false },
];
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
expect(result).toEqual([
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input', required: true },
{ type: NodeConnectionTypes.Main, index: 0, label: 'Main Input', required: true },
{
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
label: 'Optional Tool',
maxConnections: undefined,
@@ -912,9 +920,9 @@ describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
it('should map maxConnections correctly', () => {
const endpoints: INodeTypeDescription['inputs'] = [
NodeConnectionType.Main,
NodeConnectionTypes.Main,
{
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
maxConnections: 1,
displayName: 'Optional Tool',
required: false,
@@ -924,12 +932,12 @@ describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
expect(result).toEqual([
{
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
maxConnections: undefined,
index: 0,
label: undefined,
},
{ type: NodeConnectionType.AiMemory, maxConnections: 1, index: 0, label: 'Optional Tool' },
{ type: NodeConnectionTypes.AiMemory, maxConnections: 1, index: 0, label: 'Optional Tool' },
]);
});
});

View File

@@ -1,10 +1,15 @@
import type { IConnection, IConnections, INodeTypeDescription } from 'n8n-workflow';
import type {
IConnection,
IConnections,
INodeTypeDescription,
NodeConnectionType,
} from 'n8n-workflow';
import type { INodeUi } from '@/Interface';
import type { BoundingBox, CanvasConnection, CanvasConnectionPort } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { Connection } from '@vue-flow/core';
import { isValidCanvasConnectionMode, isValidNodeConnectionType } from '@/utils/typeGuards';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
/**
* Maps multiple legacy n8n connections to VueFlow connections
@@ -117,7 +122,7 @@ export function parseCanvasConnectionHandleString(handle: string | null | undefi
const [mode, type, index] = (handle ?? '').split('/');
const resolvedMode = isValidCanvasConnectionMode(mode) ? mode : CanvasConnectionMode.Output;
const resolvedType = isValidNodeConnectionType(type) ? type : NodeConnectionType.Main;
const resolvedType = isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main;
let resolvedIndex = parseInt(index, 10);
if (isNaN(resolvedIndex)) {
resolvedIndex = 0;
@@ -135,7 +140,7 @@ export function parseCanvasConnectionHandleString(handle: string | null | undefi
*/
export function createCanvasConnectionHandleString({
mode,
type = NodeConnectionType.Main,
type = NodeConnectionTypes.Main,
index = 0,
}: {
mode: 'inputs' | 'outputs';
@@ -200,7 +205,7 @@ export function mapLegacyEndpointsToCanvasConnectionPort(
return endpoints.map((endpoint, endpointIndex) => {
const typeValue = typeof endpoint === 'string' ? endpoint : endpoint.type;
const type = isValidNodeConnectionType(typeValue) ? typeValue : NodeConnectionType.Main;
const type = isValidNodeConnectionType(typeValue) ? typeValue : NodeConnectionTypes.Main;
const label =
typeof endpoint === 'string' ? endpointNames[endpointIndex] : endpoint.displayName;
const index =

View File

@@ -1,5 +1,5 @@
import type { INodeUi, WorkflowDataWithTemplateId } from '@/Interface';
import { NodeConnectionType } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
/**
* Generates a workflow JSON object for an AI Agent in n8n.
@@ -145,7 +145,7 @@ export const getEasyAiWorkflowJson = ({
[
{
node: 'AI Agent',
type: NodeConnectionType.AiTool,
type: NodeConnectionTypes.AiTool,
index: 0,
},
],
@@ -156,7 +156,7 @@ export const getEasyAiWorkflowJson = ({
[
{
node: 'AI Agent',
type: NodeConnectionType.Main,
type: NodeConnectionTypes.Main,
index: 0,
},
],
@@ -167,7 +167,7 @@ export const getEasyAiWorkflowJson = ({
[
{
node: 'AI Agent',
type: NodeConnectionType.AiLanguageModel,
type: NodeConnectionTypes.AiLanguageModel,
index: 0,
},
],
@@ -178,7 +178,7 @@ export const getEasyAiWorkflowJson = ({
[
{
node: 'AI Agent',
type: NodeConnectionType.AiMemory,
type: NodeConnectionTypes.AiMemory,
index: 0,
},
],

View File

@@ -68,8 +68,8 @@ import {
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
import { useExternalHooks } from '@/composables/useExternalHooks';
import { NodeConnectionType, jsonParse } from 'n8n-workflow';
import type { IDataObject, ExecutionSummary, IConnection } from 'n8n-workflow';
import { NodeConnectionTypes, jsonParse } from 'n8n-workflow';
import type { NodeConnectionType, IDataObject, ExecutionSummary, IConnection } from 'n8n-workflow';
import { useToast } from '@/composables/useToast';
import { useSettingsStore } from '@/stores/settings.store';
import { useCredentialsStore } from '@/stores/credentials.store';
@@ -990,19 +990,19 @@ async function onAddNodesAndConnections(
const mappedConnections: CanvasConnectionCreateData[] = connections.map(({ from, to }) => {
const fromNode = editableWorkflow.value.nodes[offsetIndex + from.nodeIndex];
const toNode = editableWorkflow.value.nodes[offsetIndex + to.nodeIndex];
const type = from.type ?? to.type ?? NodeConnectionType.Main;
const type = from.type ?? to.type ?? NodeConnectionTypes.Main;
return {
source: fromNode.id,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: isValidNodeConnectionType(type) ? type : NodeConnectionType.Main,
type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
index: from.outputIndex ?? 0,
}),
target: toNode.id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: isValidNodeConnectionType(type) ? type : NodeConnectionType.Main,
type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
index: to.inputIndex ?? 0,
}),
data: {