mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(editor): Migrate nodeTypes.store
to use composition API (no-changelog) (#9795)
This commit is contained in:
parent
15d631c412
commit
89b8d04fcd
|
@ -1,297 +1,331 @@
|
||||||
import {
|
import * as nodeTypesApi from '@/api/nodeTypes';
|
||||||
getNodeParameterOptions,
|
|
||||||
getNodesInformation,
|
|
||||||
getNodeTranslationHeaders,
|
|
||||||
getNodeTypes,
|
|
||||||
getResourceLocatorResults,
|
|
||||||
getResourceMapperFields,
|
|
||||||
} from '@/api/nodeTypes';
|
|
||||||
import { HTTP_REQUEST_NODE_TYPE, STORES, CREDENTIAL_ONLY_HTTP_NODE_VERSION } from '@/constants';
|
import { HTTP_REQUEST_NODE_TYPE, STORES, CREDENTIAL_ONLY_HTTP_NODE_VERSION } from '@/constants';
|
||||||
import type { INodeTypesState, DynamicNodeParameters } from '@/Interface';
|
import type { DynamicNodeParameters, NodeTypesByTypeNameAndVersion } from '@/Interface';
|
||||||
import { addHeaders, addNodeTranslation } from '@/plugins/i18n';
|
import { addHeaders, addNodeTranslation } from '@/plugins/i18n';
|
||||||
import { omit } from '@/utils/typesUtils';
|
import { omit } from '@/utils/typesUtils';
|
||||||
import type {
|
import type {
|
||||||
ConnectionTypes,
|
ConnectionTypes,
|
||||||
INode,
|
INode,
|
||||||
INodeListSearchResult,
|
|
||||||
INodeOutputConfiguration,
|
INodeOutputConfiguration,
|
||||||
INodePropertyOptions,
|
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
INodeTypeNameVersion,
|
INodeTypeNameVersion,
|
||||||
ResourceMapperFields,
|
|
||||||
Workflow,
|
Workflow,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
|
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { useCredentialsStore } from './credentials.store';
|
import { useCredentialsStore } from './credentials.store';
|
||||||
import { useRootStore } from './root.store';
|
import { useRootStore } from './root.store';
|
||||||
import {
|
import * as utils from '@/utils/credentialOnlyNodes';
|
||||||
getCredentialOnlyNodeType,
|
|
||||||
getCredentialTypeName,
|
|
||||||
isCredentialOnlyNodeType,
|
|
||||||
} from '@/utils/credentialOnlyNodes';
|
|
||||||
import { groupNodeTypesByNameAndType } from '@/utils/nodeTypes/nodeTypeTransforms';
|
import { groupNodeTypesByNameAndType } from '@/utils/nodeTypes/nodeTypeTransforms';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
export type NodeTypesStore = ReturnType<typeof useNodeTypesStore>;
|
export type NodeTypesStore = ReturnType<typeof useNodeTypesStore>;
|
||||||
|
|
||||||
export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, {
|
export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
|
||||||
state: (): INodeTypesState => ({
|
const nodeTypes = ref<NodeTypesByTypeNameAndVersion>({});
|
||||||
nodeTypes: {},
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
allNodeTypes(): INodeTypeDescription[] {
|
|
||||||
return Object.values(this.nodeTypes).reduce<INodeTypeDescription[]>(
|
|
||||||
(allNodeTypes, nodeType) => {
|
|
||||||
const versionNumbers = Object.keys(nodeType).map(Number);
|
|
||||||
const allNodeVersions = versionNumbers.map((version) => nodeType[version]);
|
|
||||||
|
|
||||||
return [...allNodeTypes, ...allNodeVersions];
|
const rootStore = useRootStore();
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
allLatestNodeTypes(): INodeTypeDescription[] {
|
|
||||||
return Object.values(this.nodeTypes).reduce<INodeTypeDescription[]>(
|
|
||||||
(allLatestNodeTypes, nodeVersions) => {
|
|
||||||
const versionNumbers = Object.keys(nodeVersions).map(Number);
|
|
||||||
const latestNodeVersion = nodeVersions[Math.max(...versionNumbers)];
|
|
||||||
|
|
||||||
if (!latestNodeVersion) return allLatestNodeTypes;
|
// ---------------------------------------------------------------------------
|
||||||
|
// #region Computed
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
return [...allLatestNodeTypes, latestNodeVersion];
|
const allNodeTypes = computed(() => {
|
||||||
},
|
return Object.values(nodeTypes.value).reduce<INodeTypeDescription[]>(
|
||||||
[],
|
(allNodeTypes, nodeType) => {
|
||||||
);
|
const versionNumbers = Object.keys(nodeType).map(Number);
|
||||||
},
|
const allNodeVersions = versionNumbers.map((version) => nodeType[version]);
|
||||||
getNodeType() {
|
|
||||||
return (nodeTypeName: string, version?: number): INodeTypeDescription | null => {
|
|
||||||
if (isCredentialOnlyNodeType(nodeTypeName)) {
|
|
||||||
return this.getCredentialOnlyNodeType(nodeTypeName, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeVersions = this.nodeTypes[nodeTypeName];
|
return [...allNodeTypes, ...allNodeVersions];
|
||||||
|
},
|
||||||
if (!nodeVersions) return null;
|
[],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const allLatestNodeTypes = computed(() => {
|
||||||
|
return Object.values(nodeTypes.value).reduce<INodeTypeDescription[]>(
|
||||||
|
(allLatestNodeTypes, nodeVersions) => {
|
||||||
const versionNumbers = Object.keys(nodeVersions).map(Number);
|
const versionNumbers = Object.keys(nodeVersions).map(Number);
|
||||||
const nodeType = nodeVersions[version ?? Math.max(...versionNumbers)];
|
const latestNodeVersion = nodeVersions[Math.max(...versionNumbers)];
|
||||||
return nodeType ?? null;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getNodeVersions() {
|
|
||||||
return (nodeTypeName: string): number[] => {
|
|
||||||
return Object.keys(this.nodeTypes[nodeTypeName] ?? {}).map(Number);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getCredentialOnlyNodeType() {
|
|
||||||
return (nodeTypeName: string, version?: number): INodeTypeDescription | null => {
|
|
||||||
const credentialName = getCredentialTypeName(nodeTypeName);
|
|
||||||
const httpNode = this.getNodeType(
|
|
||||||
HTTP_REQUEST_NODE_TYPE,
|
|
||||||
version ?? CREDENTIAL_ONLY_HTTP_NODE_VERSION,
|
|
||||||
);
|
|
||||||
const credential = useCredentialsStore().getCredentialTypeByName(credentialName);
|
|
||||||
return getCredentialOnlyNodeType(httpNode, credential) ?? null;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
isConfigNode() {
|
|
||||||
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
|
||||||
if (!workflow.nodes[node.name]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const nodeType = this.getNodeType(nodeTypeName);
|
|
||||||
if (!nodeType) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const outputs = NodeHelpers.getNodeOutputs(workflow, node, nodeType);
|
|
||||||
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
|
||||||
|
|
||||||
return outputTypes
|
if (!latestNodeVersion) return allLatestNodeTypes;
|
||||||
? outputTypes.filter((output) => output !== NodeConnectionType.Main).length > 0
|
|
||||||
: false;
|
return [...allLatestNodeTypes, latestNodeVersion];
|
||||||
};
|
},
|
||||||
},
|
[],
|
||||||
isConfigurableNode() {
|
);
|
||||||
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
});
|
||||||
const nodeType = this.getNodeType(nodeTypeName);
|
|
||||||
if (nodeType === null) {
|
const getNodeType = computed(() => {
|
||||||
return false;
|
return (nodeTypeName: string, version?: number): INodeTypeDescription | null => {
|
||||||
}
|
if (utils.isCredentialOnlyNodeType(nodeTypeName)) {
|
||||||
const inputs = NodeHelpers.getNodeInputs(workflow, node, nodeType);
|
return getCredentialOnlyNodeType.value(nodeTypeName, version);
|
||||||
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
}
|
||||||
|
|
||||||
|
const nodeVersions = nodeTypes.value[nodeTypeName];
|
||||||
|
|
||||||
|
if (!nodeVersions) return null;
|
||||||
|
|
||||||
|
const versionNumbers = Object.keys(nodeVersions).map(Number);
|
||||||
|
const nodeType = nodeVersions[version ?? Math.max(...versionNumbers)];
|
||||||
|
return nodeType ?? null;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const getNodeVersions = computed(() => {
|
||||||
|
return (nodeTypeName: string): number[] => {
|
||||||
|
return Object.keys(nodeTypes.value[nodeTypeName] ?? {}).map(Number);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const getCredentialOnlyNodeType = computed(() => {
|
||||||
|
return (nodeTypeName: string, version?: number): INodeTypeDescription | null => {
|
||||||
|
const credentialName = utils.getCredentialTypeName(nodeTypeName);
|
||||||
|
const httpNode = getNodeType.value(
|
||||||
|
HTTP_REQUEST_NODE_TYPE,
|
||||||
|
version ?? CREDENTIAL_ONLY_HTTP_NODE_VERSION,
|
||||||
|
);
|
||||||
|
const credential = useCredentialsStore().getCredentialTypeByName(credentialName);
|
||||||
|
return utils.getCredentialOnlyNodeType(httpNode, credential) ?? null;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const isConfigNode = computed(() => {
|
||||||
|
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
||||||
|
if (!workflow.nodes[node.name]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const nodeType = getNodeType.value(nodeTypeName);
|
||||||
|
if (!nodeType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const outputs = NodeHelpers.getNodeOutputs(workflow, node, nodeType);
|
||||||
|
const outputTypes = NodeHelpers.getConnectionTypes(outputs);
|
||||||
|
|
||||||
|
return outputTypes
|
||||||
|
? outputTypes.filter((output) => output !== NodeConnectionType.Main).length > 0
|
||||||
|
: false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const isTriggerNode = computed(() => {
|
||||||
|
return (nodeTypeName: string) => {
|
||||||
|
const nodeType = getNodeType.value(nodeTypeName);
|
||||||
|
return !!(nodeType && nodeType.group.includes('trigger'));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const isCoreNodeType = computed(() => {
|
||||||
|
return (nodeType: INodeTypeDescription) => {
|
||||||
|
return nodeType.codex?.categories?.includes('Core Nodes');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const visibleNodeTypes = computed(() => {
|
||||||
|
return allLatestNodeTypes.value.filter((nodeType: INodeTypeDescription) => !nodeType.hidden);
|
||||||
|
});
|
||||||
|
|
||||||
|
const nativelyNumberSuffixedDefaults = computed(() => {
|
||||||
|
return allNodeTypes.value.reduce<string[]>((acc, cur) => {
|
||||||
|
if (/\d$/.test(cur.defaults.name as string)) acc.push(cur.defaults.name as string);
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
const visibleNodeTypesByOutputConnectionTypeNames = computed(() => {
|
||||||
|
const nodesByOutputType = visibleNodeTypes.value.reduce(
|
||||||
|
(acc, node) => {
|
||||||
|
const outputTypes = node.outputs;
|
||||||
|
if (Array.isArray(outputTypes)) {
|
||||||
|
outputTypes.forEach((value: ConnectionTypes | INodeOutputConfiguration) => {
|
||||||
|
const outputType = typeof value === 'string' ? value : value.type;
|
||||||
|
if (!acc[outputType]) {
|
||||||
|
acc[outputType] = [];
|
||||||
|
}
|
||||||
|
acc[outputType].push(node.name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 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: ConnectionTypes[] = [
|
||||||
|
NodeConnectionType.AiVectorStore,
|
||||||
|
NodeConnectionType.AiChain,
|
||||||
|
NodeConnectionType.AiDocument,
|
||||||
|
NodeConnectionType.AiEmbedding,
|
||||||
|
NodeConnectionType.AiLanguageModel,
|
||||||
|
NodeConnectionType.AiMemory,
|
||||||
|
NodeConnectionType.AiOutputParser,
|
||||||
|
NodeConnectionType.AiTextSplitter,
|
||||||
|
NodeConnectionType.AiTool,
|
||||||
|
];
|
||||||
|
connectorTypes.forEach((outputType: ConnectionTypes) => {
|
||||||
|
if (outputTypes.includes(outputType)) {
|
||||||
|
acc[outputType] = acc[outputType] || [];
|
||||||
|
acc[outputType].push(node.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return inputTypes
|
|
||||||
? inputTypes.filter((input) => input !== NodeConnectionType.Main).length > 0
|
|
||||||
: false;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
isTriggerNode() {
|
|
||||||
return (nodeTypeName: string) => {
|
|
||||||
const nodeType = this.getNodeType(nodeTypeName);
|
|
||||||
return !!(nodeType && nodeType.group.includes('trigger'));
|
|
||||||
};
|
|
||||||
},
|
|
||||||
isCoreNodeType() {
|
|
||||||
return (nodeType: INodeTypeDescription) => {
|
|
||||||
return nodeType.codex?.categories?.includes('Core Nodes');
|
|
||||||
};
|
|
||||||
},
|
|
||||||
visibleNodeTypes(): INodeTypeDescription[] {
|
|
||||||
return this.allLatestNodeTypes.filter((nodeType: INodeTypeDescription) => !nodeType.hidden);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Getter for node default names ending with a number: `'S3'`, `'Magento 2'`, etc.
|
|
||||||
*/
|
|
||||||
nativelyNumberSuffixedDefaults(): string[] {
|
|
||||||
return this.allNodeTypes.reduce<string[]>((acc, cur) => {
|
|
||||||
if (/\d$/.test(cur.defaults.name as string)) acc.push(cur.defaults.name as string);
|
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
},
|
||||||
},
|
{} as { [key: string]: string[] },
|
||||||
visibleNodeTypesByOutputConnectionTypeNames(): { [key: string]: string[] } {
|
);
|
||||||
const nodesByOutputType = this.visibleNodeTypes.reduce(
|
|
||||||
(acc, node) => {
|
|
||||||
const outputTypes = node.outputs;
|
|
||||||
if (Array.isArray(outputTypes)) {
|
|
||||||
outputTypes.forEach((value: ConnectionTypes | INodeOutputConfiguration) => {
|
|
||||||
const outputType = typeof value === 'string' ? value : value.type;
|
|
||||||
if (!acc[outputType]) {
|
|
||||||
acc[outputType] = [];
|
|
||||||
}
|
|
||||||
acc[outputType].push(node.name);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 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: ConnectionTypes[] = [
|
|
||||||
NodeConnectionType.AiVectorStore,
|
|
||||||
NodeConnectionType.AiChain,
|
|
||||||
NodeConnectionType.AiDocument,
|
|
||||||
NodeConnectionType.AiEmbedding,
|
|
||||||
NodeConnectionType.AiLanguageModel,
|
|
||||||
NodeConnectionType.AiMemory,
|
|
||||||
NodeConnectionType.AiOutputParser,
|
|
||||||
NodeConnectionType.AiTextSplitter,
|
|
||||||
NodeConnectionType.AiTool,
|
|
||||||
];
|
|
||||||
connectorTypes.forEach((outputType: ConnectionTypes) => {
|
|
||||||
if (outputTypes.includes(outputType)) {
|
|
||||||
acc[outputType] = acc[outputType] || [];
|
|
||||||
acc[outputType].push(node.name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
return nodesByOutputType;
|
||||||
},
|
});
|
||||||
{} as { [key: string]: string[] },
|
|
||||||
);
|
|
||||||
|
|
||||||
return nodesByOutputType;
|
const visibleNodeTypesByInputConnectionTypeNames = computed(() => {
|
||||||
},
|
const nodesByOutputType = visibleNodeTypes.value.reduce(
|
||||||
visibleNodeTypesByInputConnectionTypeNames(): { [key: string]: string[] } {
|
(acc, node) => {
|
||||||
const nodesByOutputType = this.visibleNodeTypes.reduce(
|
const inputTypes = node.inputs;
|
||||||
(acc, node) => {
|
if (Array.isArray(inputTypes)) {
|
||||||
const inputTypes = node.inputs;
|
inputTypes.forEach((value: ConnectionTypes | INodeOutputConfiguration) => {
|
||||||
if (Array.isArray(inputTypes)) {
|
const outputType = typeof value === 'string' ? value : value.type;
|
||||||
inputTypes.forEach((value: ConnectionTypes | INodeOutputConfiguration) => {
|
if (!acc[outputType]) {
|
||||||
const outputType = typeof value === 'string' ? value : value.type;
|
acc[outputType] = [];
|
||||||
if (!acc[outputType]) {
|
}
|
||||||
acc[outputType] = [];
|
acc[outputType].push(node.name);
|
||||||
}
|
});
|
||||||
acc[outputType].push(node.name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{} as { [key: string]: string[] },
|
|
||||||
);
|
|
||||||
|
|
||||||
return nodesByOutputType;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
setNodeTypes(newNodeTypes: INodeTypeDescription[] = []): void {
|
|
||||||
const nodeTypes = groupNodeTypesByNameAndType(newNodeTypes);
|
|
||||||
this.nodeTypes = {
|
|
||||||
...this.nodeTypes,
|
|
||||||
...nodeTypes,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
removeNodeTypes(nodeTypesToRemove: INodeTypeDescription[]): void {
|
|
||||||
this.nodeTypes = nodeTypesToRemove.reduce(
|
|
||||||
(oldNodes, newNodeType) => omit(newNodeType.name, oldNodes),
|
|
||||||
this.nodeTypes,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
async getNodesInformation(
|
|
||||||
nodeInfos: INodeTypeNameVersion[],
|
|
||||||
replace = true,
|
|
||||||
): Promise<INodeTypeDescription[]> {
|
|
||||||
const rootStore = useRootStore();
|
|
||||||
const nodesInformation = await getNodesInformation(rootStore.restApiContext, nodeInfos);
|
|
||||||
|
|
||||||
nodesInformation.forEach((nodeInformation) => {
|
|
||||||
if (nodeInformation.translation) {
|
|
||||||
const nodeType = nodeInformation.name.replace('n8n-nodes-base.', '');
|
|
||||||
|
|
||||||
addNodeTranslation({ [nodeType]: nodeInformation.translation }, rootStore.defaultLocale);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
if (replace) this.setNodeTypes(nodesInformation);
|
|
||||||
|
|
||||||
return nodesInformation;
|
return acc;
|
||||||
},
|
},
|
||||||
async getFullNodesProperties(nodesToBeFetched: INodeTypeNameVersion[]): Promise<void> {
|
{} as { [key: string]: string[] },
|
||||||
const credentialsStore = useCredentialsStore();
|
);
|
||||||
await credentialsStore.fetchCredentialTypes(true);
|
|
||||||
await this.getNodesInformation(nodesToBeFetched);
|
|
||||||
},
|
|
||||||
async getNodeTypes(): Promise<void> {
|
|
||||||
const rootStore = useRootStore();
|
|
||||||
const nodeTypes = await getNodeTypes(rootStore.baseUrl);
|
|
||||||
if (nodeTypes.length) {
|
|
||||||
this.setNodeTypes(nodeTypes);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Loads node types if they haven't been loaded yet
|
|
||||||
*/
|
|
||||||
async loadNodeTypesIfNotLoaded(): Promise<void> {
|
|
||||||
if (Object.keys(this.nodeTypes).length === 0) {
|
|
||||||
await this.getNodeTypes();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getNodeTranslationHeaders(): Promise<void> {
|
|
||||||
const rootStore = useRootStore();
|
|
||||||
const headers = await getNodeTranslationHeaders(rootStore.restApiContext);
|
|
||||||
|
|
||||||
if (headers) {
|
return nodesByOutputType;
|
||||||
addHeaders(headers, rootStore.defaultLocale);
|
});
|
||||||
|
|
||||||
|
const isConfigurableNode = computed(() => {
|
||||||
|
return (workflow: Workflow, node: INode, nodeTypeName: string): boolean => {
|
||||||
|
const nodeType = getNodeType.value(nodeTypeName);
|
||||||
|
if (nodeType === null) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
const inputs = NodeHelpers.getNodeInputs(workflow, node, nodeType);
|
||||||
async getNodeParameterOptions(
|
const inputTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||||
sendData: DynamicNodeParameters.OptionsRequest,
|
|
||||||
): Promise<INodePropertyOptions[]> {
|
return inputTypes
|
||||||
const rootStore = useRootStore();
|
? inputTypes.filter((input) => input !== NodeConnectionType.Main).length > 0
|
||||||
return await getNodeParameterOptions(rootStore.restApiContext, sendData);
|
: false;
|
||||||
},
|
};
|
||||||
async getResourceLocatorResults(
|
});
|
||||||
sendData: DynamicNodeParameters.ResourceLocatorResultsRequest,
|
|
||||||
): Promise<INodeListSearchResult> {
|
// #endregion
|
||||||
const rootStore = useRootStore();
|
|
||||||
return await getResourceLocatorResults(rootStore.restApiContext, sendData);
|
// ---------------------------------------------------------------------------
|
||||||
},
|
// #region Methods
|
||||||
async getResourceMapperFields(
|
// ---------------------------------------------------------------------------
|
||||||
sendData: DynamicNodeParameters.ResourceMapperFieldsRequest,
|
|
||||||
): Promise<ResourceMapperFields | null> {
|
const setNodeTypes = (newNodeTypes: INodeTypeDescription[] = []) => {
|
||||||
const rootStore = useRootStore();
|
const groupedNodeTypes = groupNodeTypesByNameAndType(newNodeTypes);
|
||||||
try {
|
nodeTypes.value = {
|
||||||
return await getResourceMapperFields(rootStore.restApiContext, sendData);
|
...nodeTypes.value,
|
||||||
} catch (error) {
|
...groupedNodeTypes,
|
||||||
return null;
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeNodeTypes = (nodeTypesToRemove: INodeTypeDescription[]) => {
|
||||||
|
nodeTypes.value = nodeTypesToRemove.reduce(
|
||||||
|
(oldNodes, newNodeType) => omit(newNodeType.name, oldNodes),
|
||||||
|
nodeTypes.value,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodesInformation = async (
|
||||||
|
nodeInfos: INodeTypeNameVersion[],
|
||||||
|
replace = true,
|
||||||
|
): Promise<INodeTypeDescription[]> => {
|
||||||
|
const nodesInformation = await nodeTypesApi.getNodesInformation(
|
||||||
|
rootStore.restApiContext,
|
||||||
|
nodeInfos,
|
||||||
|
);
|
||||||
|
|
||||||
|
nodesInformation.forEach((nodeInformation) => {
|
||||||
|
if (nodeInformation.translation) {
|
||||||
|
const nodeType = nodeInformation.name.replace('n8n-nodes-base.', '');
|
||||||
|
|
||||||
|
addNodeTranslation({ [nodeType]: nodeInformation.translation }, rootStore.defaultLocale);
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
},
|
if (replace) setNodeTypes(nodesInformation);
|
||||||
|
|
||||||
|
return nodesInformation;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFullNodesProperties = async (nodesToBeFetched: INodeTypeNameVersion[]) => {
|
||||||
|
const credentialsStore = useCredentialsStore();
|
||||||
|
await credentialsStore.fetchCredentialTypes(true);
|
||||||
|
await getNodesInformation(nodesToBeFetched);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodeTypes = async () => {
|
||||||
|
const nodeTypes = await nodeTypesApi.getNodeTypes(rootStore.baseUrl);
|
||||||
|
if (nodeTypes.length) {
|
||||||
|
setNodeTypes(nodeTypes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadNodeTypesIfNotLoaded = async () => {
|
||||||
|
if (Object.keys(nodeTypes.value).length === 0) {
|
||||||
|
await getNodeTypes();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodeTranslationHeaders = async () => {
|
||||||
|
const headers = await nodeTypesApi.getNodeTranslationHeaders(rootStore.restApiContext);
|
||||||
|
|
||||||
|
if (headers) {
|
||||||
|
addHeaders(headers, rootStore.defaultLocale);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodeParameterOptions = async (sendData: DynamicNodeParameters.OptionsRequest) => {
|
||||||
|
return await nodeTypesApi.getNodeParameterOptions(rootStore.restApiContext, sendData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getResourceLocatorResults = async (
|
||||||
|
sendData: DynamicNodeParameters.ResourceLocatorResultsRequest,
|
||||||
|
) => {
|
||||||
|
return await nodeTypesApi.getResourceLocatorResults(rootStore.restApiContext, sendData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getResourceMapperFields = async (
|
||||||
|
sendData: DynamicNodeParameters.ResourceMapperFieldsRequest,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
return await nodeTypesApi.getResourceMapperFields(rootStore.restApiContext, sendData);
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodeTypes,
|
||||||
|
allNodeTypes,
|
||||||
|
allLatestNodeTypes,
|
||||||
|
getNodeType,
|
||||||
|
getNodeVersions,
|
||||||
|
getCredentialOnlyNodeType,
|
||||||
|
isConfigNode,
|
||||||
|
isTriggerNode,
|
||||||
|
isCoreNodeType,
|
||||||
|
visibleNodeTypes,
|
||||||
|
nativelyNumberSuffixedDefaults,
|
||||||
|
visibleNodeTypesByOutputConnectionTypeNames,
|
||||||
|
visibleNodeTypesByInputConnectionTypeNames,
|
||||||
|
isConfigurableNode,
|
||||||
|
getResourceMapperFields,
|
||||||
|
getResourceLocatorResults,
|
||||||
|
getNodeParameterOptions,
|
||||||
|
getNodesInformation,
|
||||||
|
getFullNodesProperties,
|
||||||
|
getNodeTypes,
|
||||||
|
loadNodeTypesIfNotLoaded,
|
||||||
|
getNodeTranslationHeaders,
|
||||||
|
setNodeTypes,
|
||||||
|
removeNodeTypes,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue