mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
feat(Set Node): Preserve binary data by default (#9668)
Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
@@ -577,17 +577,17 @@ describe('NDV', () => {
|
|||||||
|
|
||||||
workflowPage.actions.openNode('Edit Fields (old)');
|
workflowPage.actions.openNode('Edit Fields (old)');
|
||||||
ndv.actions.openSettings();
|
ndv.actions.openSettings();
|
||||||
ndv.getters.nodeVersion().should('have.text', 'Set node version 2 (Latest version: 3.3)');
|
ndv.getters.nodeVersion().should('have.text', 'Set node version 2 (Latest version: 3.4)');
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
|
||||||
workflowPage.actions.openNode('Edit Fields (latest)');
|
workflowPage.actions.openNode('Edit Fields (latest)');
|
||||||
ndv.actions.openSettings();
|
ndv.actions.openSettings();
|
||||||
ndv.getters.nodeVersion().should('have.text', 'Edit Fields (Set) node version 3.3 (Latest)');
|
ndv.getters.nodeVersion().should('have.text', 'Edit Fields (Set) node version 3.4 (Latest)');
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
|
||||||
workflowPage.actions.openNode('Edit Fields (no typeVersion)');
|
workflowPage.actions.openNode('Edit Fields (no typeVersion)');
|
||||||
ndv.actions.openSettings();
|
ndv.actions.openSettings();
|
||||||
ndv.getters.nodeVersion().should('have.text', 'Edit Fields (Set) node version 3.3 (Latest)');
|
ndv.getters.nodeVersion().should('have.text', 'Edit Fields (Set) node version 3.4 (Latest)');
|
||||||
ndv.actions.close();
|
ndv.actions.close();
|
||||||
|
|
||||||
workflowPage.actions.openNode('Function');
|
workflowPage.actions.openNode('Function');
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"id": "273f60c9-08e7-457e-b01d-31e16c565171",
|
"id": "273f60c9-08e7-457e-b01d-31e16c565171",
|
||||||
"name": "Edit Fields (latest)",
|
"name": "Edit Fields (latest)",
|
||||||
"type": "n8n-nodes-base.set",
|
"type": "n8n-nodes-base.set",
|
||||||
"typeVersion": 3.3,
|
"typeVersion": 3.4,
|
||||||
"position": [640, 460]
|
"position": [640, 460]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ const iconSource = computed<NodeIconSource>(() => {
|
|||||||
// Otherwise, extract it from icon prop
|
// Otherwise, extract it from icon prop
|
||||||
if (nodeType.icon) {
|
if (nodeType.icon) {
|
||||||
const icon = getNodeIcon(nodeType, uiStore.appliedTheme);
|
const icon = getNodeIcon(nodeType, uiStore.appliedTheme);
|
||||||
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
const [type, path] = icon.split(':');
|
const [type, path] = icon.split(':');
|
||||||
if (type === 'file') {
|
if (type === 'file') {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class Set extends VersionedNodeType {
|
|||||||
icon: 'fa:pen',
|
icon: 'fa:pen',
|
||||||
group: ['input'],
|
group: ['input'],
|
||||||
description: 'Add or edit fields on an input item and optionally remove other fields',
|
description: 'Add or edit fields on an input item and optionally remove other fields',
|
||||||
defaultVersion: 3.3,
|
defaultVersion: 3.4,
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
|
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
|
||||||
@@ -22,6 +22,7 @@ export class Set extends VersionedNodeType {
|
|||||||
3.1: new SetV2(baseDescription),
|
3.1: new SetV2(baseDescription),
|
||||||
3.2: new SetV2(baseDescription),
|
3.2: new SetV2(baseDescription),
|
||||||
3.3: new SetV2(baseDescription),
|
3.3: new SetV2(baseDescription),
|
||||||
|
3.4: new SetV2(baseDescription),
|
||||||
};
|
};
|
||||||
|
|
||||||
super(nodeVersions, baseDescription);
|
super(nodeVersions, baseDescription);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ describe('test Set2, composeReturnItem', () => {
|
|||||||
include: 'none',
|
include: 'none',
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = composeReturnItem.call(fakeExecuteFunction, 0, inputItem, newData, options);
|
const result = composeReturnItem.call(fakeExecuteFunction, 0, inputItem, newData, options, 3.4);
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
json: {
|
json: {
|
||||||
@@ -114,7 +114,7 @@ describe('test Set2, composeReturnItem', () => {
|
|||||||
include: 'selected',
|
include: 'selected',
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = composeReturnItem.call(fakeExecuteFunction, 0, inputItem, newData, options);
|
const result = composeReturnItem.call(fakeExecuteFunction, 0, inputItem, newData, options, 3.4);
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
json: {
|
json: {
|
||||||
@@ -132,6 +132,122 @@ describe('test Set2, composeReturnItem', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should include binary when expected in version <3.4', () => {
|
||||||
|
const fakeExecuteFunction = createMockExecuteFunction({});
|
||||||
|
|
||||||
|
const inputItem = {
|
||||||
|
json: {
|
||||||
|
input1: 'value1',
|
||||||
|
input2: 2,
|
||||||
|
input3: [1, 2, 3],
|
||||||
|
},
|
||||||
|
pairedItem: {
|
||||||
|
item: 0,
|
||||||
|
input: undefined,
|
||||||
|
},
|
||||||
|
binary: {
|
||||||
|
data: {
|
||||||
|
data: 'content',
|
||||||
|
mimeType: 'image/jpg',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const newData = {
|
||||||
|
num1: 55,
|
||||||
|
str1: '42',
|
||||||
|
arr1: ['foo', 'bar'],
|
||||||
|
obj: {
|
||||||
|
key: 'value',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const resultWithIncludeBinary = composeReturnItem.call(
|
||||||
|
fakeExecuteFunction,
|
||||||
|
0,
|
||||||
|
inputItem,
|
||||||
|
newData,
|
||||||
|
{
|
||||||
|
include: 'all',
|
||||||
|
includeBinary: true,
|
||||||
|
},
|
||||||
|
3.3,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resultWithIncludeBinary.binary).toEqual(inputItem.binary);
|
||||||
|
|
||||||
|
const resultWithoutIncludeBinary = composeReturnItem.call(
|
||||||
|
fakeExecuteFunction,
|
||||||
|
0,
|
||||||
|
inputItem,
|
||||||
|
newData,
|
||||||
|
{
|
||||||
|
include: 'all',
|
||||||
|
},
|
||||||
|
3.3,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resultWithoutIncludeBinary.binary).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include binary when expected in version >=3.4', () => {
|
||||||
|
const fakeExecuteFunction = createMockExecuteFunction({});
|
||||||
|
|
||||||
|
const inputItem = {
|
||||||
|
json: {
|
||||||
|
input1: 'value1',
|
||||||
|
input2: 2,
|
||||||
|
input3: [1, 2, 3],
|
||||||
|
},
|
||||||
|
pairedItem: {
|
||||||
|
item: 0,
|
||||||
|
input: undefined,
|
||||||
|
},
|
||||||
|
binary: {
|
||||||
|
data: {
|
||||||
|
data: 'content',
|
||||||
|
mimeType: 'image/jpg',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const newData = {
|
||||||
|
num1: 55,
|
||||||
|
str1: '42',
|
||||||
|
arr1: ['foo', 'bar'],
|
||||||
|
obj: {
|
||||||
|
key: 'value',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const resultWithStripBinary = composeReturnItem.call(
|
||||||
|
fakeExecuteFunction,
|
||||||
|
0,
|
||||||
|
inputItem,
|
||||||
|
newData,
|
||||||
|
{
|
||||||
|
include: 'all',
|
||||||
|
stripBinary: true,
|
||||||
|
},
|
||||||
|
3.4,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resultWithStripBinary.binary).toBeUndefined();
|
||||||
|
|
||||||
|
const resultWithoutStripBinary = composeReturnItem.call(
|
||||||
|
fakeExecuteFunction,
|
||||||
|
0,
|
||||||
|
inputItem,
|
||||||
|
newData,
|
||||||
|
{
|
||||||
|
include: 'all',
|
||||||
|
},
|
||||||
|
3.4,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resultWithoutStripBinary.binary).toEqual(inputItem.binary);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('test Set2, parseJsonParameter', () => {
|
describe('test Set2, parseJsonParameter', () => {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const versionDescription: INodeTypeDescription = {
|
|||||||
name: 'set',
|
name: 'set',
|
||||||
iconColor: 'blue',
|
iconColor: 'blue',
|
||||||
group: ['input'],
|
group: ['input'],
|
||||||
version: [3, 3.1, 3.2, 3.3],
|
version: [3, 3.1, 3.2, 3.3, 3.4],
|
||||||
description: 'Modify, add, or remove item fields',
|
description: 'Modify, add, or remove item fields',
|
||||||
subtitle: '={{$parameter["mode"]}}',
|
subtitle: '={{$parameter["mode"]}}',
|
||||||
defaults: {
|
defaults: {
|
||||||
@@ -208,8 +208,27 @@ const versionDescription: INodeTypeDescription = {
|
|||||||
name: 'includeBinary',
|
name: 'includeBinary',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: true,
|
default: true,
|
||||||
|
displayOptions: {
|
||||||
|
hide: {
|
||||||
|
'@version': [{ _cnd: { gte: 3.4 } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
description: 'Whether binary data should be included if present in the input item',
|
description: 'Whether binary data should be included if present in the input item',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Strip Binary Data',
|
||||||
|
name: 'stripBinary',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description:
|
||||||
|
'Whether binary data should be stripped from the input item. Only applies when "Include Other Input Fields" is enabled.',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'@version': [{ _cnd: { gte: 3.4 } }],
|
||||||
|
'/includeOtherFields': [true],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Ignore Type Conversion Errors',
|
displayName: 'Ignore Type Conversion Errors',
|
||||||
name: 'ignoreConversionErrors',
|
name: 'ignoreConversionErrors',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export type SetNodeOptions = {
|
|||||||
ignoreConversionErrors?: boolean;
|
ignoreConversionErrors?: boolean;
|
||||||
include?: IncludeMods;
|
include?: IncludeMods;
|
||||||
includeBinary?: boolean;
|
includeBinary?: boolean;
|
||||||
|
stripBinary?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SetField = {
|
export type SetField = {
|
||||||
|
|||||||
@@ -56,13 +56,17 @@ export function composeReturnItem(
|
|||||||
inputItem: INodeExecutionData,
|
inputItem: INodeExecutionData,
|
||||||
newFields: IDataObject,
|
newFields: IDataObject,
|
||||||
options: SetNodeOptions,
|
options: SetNodeOptions,
|
||||||
|
nodeVersion: number,
|
||||||
) {
|
) {
|
||||||
const newItem: INodeExecutionData = {
|
const newItem: INodeExecutionData = {
|
||||||
json: {},
|
json: {},
|
||||||
pairedItem: { item: itemIndex },
|
pairedItem: { item: itemIndex },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.includeBinary && inputItem.binary !== undefined) {
|
const includeBinary =
|
||||||
|
(nodeVersion >= 3.4 && !options.stripBinary && options.include !== 'none') ||
|
||||||
|
(nodeVersion < 3.4 && !!options.includeBinary);
|
||||||
|
if (includeBinary && inputItem.binary !== undefined) {
|
||||||
// Create a shallow copy of the binary data so that the old
|
// Create a shallow copy of the binary data so that the old
|
||||||
// data references which do not get changed still stay behind
|
// data references which do not get changed still stay behind
|
||||||
// but the incoming data does not get changed.
|
// but the incoming data does not get changed.
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export async function execute(
|
|||||||
newData[name] = value;
|
newData[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return composeReturnItem.call(this, i, item, newData, options);
|
return composeReturnItem.call(this, i, item, newData, options, node.typeVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignmentCollection = this.getNodeParameter(
|
const assignmentCollection = this.getNodeParameter(
|
||||||
@@ -247,7 +247,7 @@ export async function execute(
|
|||||||
return [name, value];
|
return [name, value];
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return composeReturnItem.call(this, i, item, newData, options);
|
return composeReturnItem.call(this, i, item, newData, options, node.typeVersion);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.continueOnFail()) {
|
if (this.continueOnFail()) {
|
||||||
return { json: { error: (error as Error).message, pairedItem: { item: i } } };
|
return { json: { error: (error as Error).message, pairedItem: { item: i } } };
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export async function execute(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return composeReturnItem.call(this, i, item, newData, options);
|
return composeReturnItem.call(this, i, item, newData, options, node.typeVersion);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.continueOnFail()) {
|
if (this.continueOnFail()) {
|
||||||
return { json: { error: (error as Error).message }, pairedItem: { item: i } };
|
return { json: { error: (error as Error).message }, pairedItem: { item: i } };
|
||||||
|
|||||||
Reference in New Issue
Block a user