mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(core): Introduce simplified node versioning (#3205)
* ✨ Introduce simple node versioning * ⚡ Add example how to read version in node-code for custom logic * 🐛 Fix setting of parameters * 🐛 Fix another instance where it sets the wrong parameter * ⚡ Remove unnecessary TOODs * ⚡ Revert Set Node example changes * ;rotating_light: Add test
This commit is contained in:
@@ -1113,7 +1113,7 @@ export interface IRequestOptionsFromParameters {
|
||||
}
|
||||
|
||||
export interface INodeTypeDescription extends INodeTypeBaseDescription {
|
||||
version: number;
|
||||
version: number | number[];
|
||||
defaults: INodeParameters;
|
||||
eventTriggerDescription?: string;
|
||||
activationMessage?: string;
|
||||
|
||||
@@ -265,6 +265,7 @@ export function getSpecialNodeParameters(nodeType: INodeType): INodeProperties[]
|
||||
export function displayParameter(
|
||||
nodeValues: INodeParameters,
|
||||
parameter: INodeProperties | INodeCredentialDescription,
|
||||
node: INode | null, // Allow null as it does also get used by credentials and they do not have versioning yet
|
||||
nodeValuesRoot?: INodeParameters,
|
||||
) {
|
||||
if (!parameter.displayOptions) {
|
||||
@@ -282,6 +283,8 @@ export function displayParameter(
|
||||
if (propertyName.charAt(0) === '/') {
|
||||
// Get the value from the root of the node
|
||||
value = get(nodeValuesRoot, propertyName.slice(1));
|
||||
} else if (propertyName === '@version') {
|
||||
value = node?.typeVersion || 0;
|
||||
} else {
|
||||
// Get the value from current level
|
||||
value = get(nodeValues, propertyName);
|
||||
@@ -313,6 +316,8 @@ export function displayParameter(
|
||||
if (propertyName.charAt(0) === '/') {
|
||||
// Get the value from the root of the node
|
||||
value = get(nodeValuesRoot, propertyName.slice(1));
|
||||
} else if (propertyName === '@version') {
|
||||
value = node?.typeVersion || 0;
|
||||
} else {
|
||||
// Get the value from current level
|
||||
value = get(nodeValues, propertyName);
|
||||
@@ -352,6 +357,7 @@ export function displayParameterPath(
|
||||
nodeValues: INodeParameters,
|
||||
parameter: INodeProperties | INodeCredentialDescription,
|
||||
path: string,
|
||||
node: INode | null,
|
||||
) {
|
||||
let resolvedNodeValues = nodeValues;
|
||||
if (path !== '') {
|
||||
@@ -364,7 +370,7 @@ export function displayParameterPath(
|
||||
nodeValuesRoot = get(nodeValues, 'parameters') as INodeParameters;
|
||||
}
|
||||
|
||||
return displayParameter(resolvedNodeValues, parameter, nodeValuesRoot);
|
||||
return displayParameter(resolvedNodeValues, parameter, node, nodeValuesRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,6 +439,10 @@ export function getParamterDependencies(
|
||||
// @ts-ignore
|
||||
for (parameterName of Object.keys(nodeProperties.displayOptions[displayRule])) {
|
||||
if (!dependencies[nodeProperties.name].includes(parameterName)) {
|
||||
if (parameterName.charAt(0) === '@') {
|
||||
// Is a special parameter so can be skipped
|
||||
continue;
|
||||
}
|
||||
dependencies[nodeProperties.name].push(parameterName);
|
||||
}
|
||||
}
|
||||
@@ -532,6 +542,7 @@ export function getNodeParameters(
|
||||
nodeValues: INodeParameters,
|
||||
returnDefaults: boolean,
|
||||
returnNoneDisplayed: boolean,
|
||||
node: INode | null,
|
||||
onlySimpleTypes = false,
|
||||
dataIsResolved = false,
|
||||
nodeValuesRoot?: INodeParameters,
|
||||
@@ -566,6 +577,7 @@ export function getNodeParameters(
|
||||
nodeValues,
|
||||
true,
|
||||
true,
|
||||
node,
|
||||
true,
|
||||
true,
|
||||
nodeValuesRoot,
|
||||
@@ -594,7 +606,7 @@ export function getNodeParameters(
|
||||
|
||||
if (
|
||||
!returnNoneDisplayed &&
|
||||
!displayParameter(nodeValuesDisplayCheck, nodeProperties, nodeValuesRoot)
|
||||
!displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeValuesRoot)
|
||||
) {
|
||||
if (!returnNoneDisplayed || !returnDefaults) {
|
||||
continue;
|
||||
@@ -605,7 +617,7 @@ export function getNodeParameters(
|
||||
// Is a simple property so can be set as it is
|
||||
|
||||
if (duplicateParameterNames.includes(nodeProperties.name)) {
|
||||
if (!displayParameter(nodeValuesDisplayCheck, nodeProperties, nodeValuesRoot)) {
|
||||
if (!displayParameter(nodeValuesDisplayCheck, nodeProperties, node, nodeValuesRoot)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -677,6 +689,7 @@ export function getNodeParameters(
|
||||
nodeValues[nodeProperties.name] as INodeParameters,
|
||||
returnDefaults,
|
||||
returnNoneDisplayed,
|
||||
node,
|
||||
false,
|
||||
false,
|
||||
nodeValuesRoot,
|
||||
@@ -737,6 +750,7 @@ export function getNodeParameters(
|
||||
nodeValue,
|
||||
returnDefaults,
|
||||
returnNoneDisplayed,
|
||||
node,
|
||||
false,
|
||||
false,
|
||||
nodeValuesRoot,
|
||||
@@ -764,6 +778,7 @@ export function getNodeParameters(
|
||||
(nodeValues[nodeProperties.name] as INodeParameters)[itemName] as INodeParameters,
|
||||
returnDefaults,
|
||||
returnNoneDisplayed,
|
||||
node,
|
||||
false,
|
||||
false,
|
||||
nodeValuesRoot,
|
||||
@@ -1021,7 +1036,7 @@ export function getNodeParametersIssues(
|
||||
}
|
||||
|
||||
for (const nodeProperty of nodePropertiesArray) {
|
||||
propertyIssues = getParameterIssues(nodeProperty, node.parameters, '');
|
||||
propertyIssues = getParameterIssues(nodeProperty, node.parameters, '', node);
|
||||
mergeIssues(foundIssues, propertyIssues);
|
||||
}
|
||||
|
||||
@@ -1135,12 +1150,13 @@ export function getParameterIssues(
|
||||
nodeProperties: INodeProperties,
|
||||
nodeValues: INodeParameters,
|
||||
path: string,
|
||||
node: INode,
|
||||
): INodeIssues {
|
||||
const foundIssues: INodeIssues = {};
|
||||
let value;
|
||||
|
||||
if (nodeProperties.required === true) {
|
||||
if (displayParameterPath(nodeValues, nodeProperties, path)) {
|
||||
if (displayParameterPath(nodeValues, nodeProperties, path, node)) {
|
||||
value = getParameterValueByPath(nodeValues, nodeProperties.name, path);
|
||||
|
||||
if (
|
||||
@@ -1235,7 +1251,7 @@ export function getParameterIssues(
|
||||
let propertyIssues;
|
||||
|
||||
for (const optionData of checkChildNodeProperties) {
|
||||
propertyIssues = getParameterIssues(optionData.data, nodeValues, optionData.basePath);
|
||||
propertyIssues = getParameterIssues(optionData.data, nodeValues, optionData.basePath, node);
|
||||
mergeIssues(foundIssues, propertyIssues);
|
||||
}
|
||||
|
||||
|
||||
@@ -586,7 +586,14 @@ export class RoutingNode {
|
||||
};
|
||||
let basePath = path ? `${path}.` : '';
|
||||
|
||||
if (!NodeHelpers.displayParameter(this.node.parameters, nodeProperties, this.node.parameters)) {
|
||||
if (
|
||||
!NodeHelpers.displayParameter(
|
||||
this.node.parameters,
|
||||
nodeProperties,
|
||||
this.node,
|
||||
this.node.parameters,
|
||||
)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
if (nodeProperties.routing) {
|
||||
|
||||
@@ -110,6 +110,7 @@ export class Workflow {
|
||||
node.parameters,
|
||||
true,
|
||||
false,
|
||||
node,
|
||||
);
|
||||
node.parameters = nodeParameters !== null ? nodeParameters : {};
|
||||
}
|
||||
|
||||
@@ -3018,6 +3018,7 @@ describe('Workflow', () => {
|
||||
testData.input.nodeValues,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
);
|
||||
expect(result).toEqual(testData.output.noneDisplayedFalse.defaultsFalse);
|
||||
|
||||
@@ -3027,6 +3028,7 @@ describe('Workflow', () => {
|
||||
testData.input.nodeValues,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
);
|
||||
expect(result).toEqual(testData.output.noneDisplayedFalse.defaultsTrue);
|
||||
|
||||
@@ -3036,6 +3038,7 @@ describe('Workflow', () => {
|
||||
testData.input.nodeValues,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
);
|
||||
expect(result).toEqual(testData.output.noneDisplayedTrue.defaultsFalse);
|
||||
|
||||
@@ -3045,6 +3048,7 @@ describe('Workflow', () => {
|
||||
testData.input.nodeValues,
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
);
|
||||
expect(result).toEqual(testData.output.noneDisplayedTrue.defaultsTrue);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user