feat: Add assignment component with drag and drop to Set node (#8283)

Co-authored-by: Giulio Andreini <andreini@netseven.it>
This commit is contained in:
Elias Meire
2024-02-06 18:34:34 +01:00
committed by GitHub
parent c04f92f7fd
commit 2799de491b
53 changed files with 3296 additions and 1060 deletions

View File

@@ -12,7 +12,7 @@ export class Set extends VersionedNodeType {
icon: 'fa:pen',
group: ['input'],
description: 'Add or edit fields on an input item and optionally remove other fields',
defaultVersion: 3.2,
defaultVersion: 3.3,
};
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
@@ -21,6 +21,7 @@ export class Set extends VersionedNodeType {
3: new SetV2(baseDescription),
3.1: new SetV2(baseDescription),
3.2: new SetV2(baseDescription),
3.3: new SetV2(baseDescription),
};
super(nodeVersions, baseDescription);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,806 @@
{
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "27cc9b56542ad45b38725555722c50a1c3fee1670bbb67980558314ee08517c4"
},
"nodes": [
{
"parameters": {},
"id": "487e9636-56d5-4955-9193-17dee520bdd0",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [160, 4240]
},
{
"parameters": {
"jsCode": "return [\n {\n \"string\": {\n test2: \"hello\",\n test3: \" \",\n test4: \"\",\n test5: \"3\",\n test6: \"3,14\",\n test7: \"3.14\",\n test8: \"false\",\n test8: \"TRUE\",\n test9: \"false\",\n test10: \"1\",\n test11: '[\"apples\", \"oranges\"]',\n test12: '\"apples\", \"oranges\"',\n test13: '[1, 2]',\n test14: '{\"a\": 1, \"b\": { \"c\": 10, \"d\": \"test\"}}',\n test15: '{\"a\": 1}',\n test16: \"null\",\n test17: \"undefined\",\n test18: \"0\",\n },\n \"number\": {\n test1: 52472,\n test2: -1,\n test3: 0,\n test4: 1.334535,\n test5: null,\n test6: undefined,\n test7: 1,\n },\n \"boolean\": {\n // test1: 1,\n // test2: 0,\n test3: true,\n test4: false,\n },\n \"date\": {\n test1: $now,\n test2: \"2023-08-01T12:34:56Z\",\n test3: \"2016-05-25T09:24:15.123\",\n test4: \"Tue, 01 Nov 2016 13:23:12 +0630\",\n test5: \"2017-05-15 09:24:15\",\n test6: \"1542674993\",\n test7: 1542674993,\n },\n \"array\": {\n test13: [1,2,3,4],\n },\n \"object\": {\n obj: {\n objKey: 2,\n objArray: [1,2,3,4],\n objBool: true\n }\n },\n }\n];"
},
"id": "8afc51b7-f9ed-417a-a58b-2fe251ba4b93",
"name": "Code1",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [420, 4240]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "numberToString1",
"type": "string",
"value": "={{ $json.number.test1 }}"
},
{
"id": "2",
"name": "numberToString2",
"type": "string",
"value": "={{ $json.number.test2 }}"
},
{
"id": "3",
"name": "numberToString3",
"type": "string",
"value": "={{ $json.number.test4 }}"
},
{
"id": "1",
"name": "boolToString1",
"type": "string",
"value": "={{ $json.boolean.test3 }}"
},
{
"id": "4",
"name": "boolToString2",
"type": "string",
"value": "={{ $json.boolean.test4 }}"
},
{
"id": "5",
"name": "arrayToString1",
"type": "string",
"value": "={{ $json.array.test13 }}"
},
{
"id": "6",
"name": "objectToString1",
"type": "string",
"value": "={{ $json.object.obj }}"
}
]
},
"options": {}
},
"id": "8ede737c-5648-4c8e-82b7-fa5193d8ff92",
"name": "To String",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [780, 3860]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToNumber1",
"type": "number",
"value": "={{ $json.string.test5 }}"
},
{
"id": "2",
"name": "stringToNumber2",
"type": "number",
"value": "={{ $json.string.test7 }}"
},
{
"id": "3",
"name": "boolToNumber1",
"type": "number",
"value": "={{ $json.boolean.test3 }}"
},
{
"id": "4",
"name": "boolToNumber2",
"type": "number",
"value": "={{ $json.boolean.test4 }}"
}
]
},
"options": {}
},
"id": "064976c4-b13d-4e2e-9a07-bab165b0efd7",
"name": "To Number",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [780, 4060]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToBoolean1",
"type": "boolean",
"value": "={{ $json.string.test8 }}"
},
{
"id": "2",
"name": "stringToBoolean3",
"type": "boolean",
"value": "={{ $json.string.test9 }}"
},
{
"id": "3",
"name": "stringToBoolean4",
"type": "boolean",
"value": "={{ $json.string.test10 }}"
},
{
"id": "4",
"name": "stringToBoolean5",
"type": "boolean",
"value": "={{ $json.string.test18 }}"
},
{
"id": "5",
"name": "numberToBoolean1",
"type": "boolean",
"value": "={{ $json.number.test3 }}"
},
{
"id": "6",
"name": "numberToBoolean2",
"type": "boolean",
"value": "={{ $json.number.test7 }}"
}
]
},
"options": {}
},
"id": "dfcdddde-cf89-44c5-94e7-f11e1f7e1a58",
"name": "To Boolean",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [780, 4240]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToArray1",
"type": "array",
"value": "={{ $json.string.test11 }}"
},
{
"id": "2",
"name": "stringToArray2",
"type": "array",
"value": "={{ $json.string.test13 }}"
},
{
"id": "3",
"name": "arrayToArray1",
"type": "array",
"value": "={{ $json.array.test13 }}"
}
]
},
"options": {}
},
"id": "7ea149df-c231-40fc-a95c-c062860896e6",
"name": "To Array",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [780, 4440]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToObject1",
"type": "object",
"value": "={{ $json.string.test14 }}"
},
{
"id": "2",
"name": "stringToObject2",
"type": "object",
"value": "={{ $json.string.test15 }}"
}
]
},
"options": {}
},
"id": "c775efa3-2508-466d-93b9-51d4c5ca9eca",
"name": "To Object",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [780, 4620]
},
{
"parameters": {
"content": "### Strict type checking",
"height": 1063.125,
"width": 369.6875
},
"id": "d646183a-b6ea-48e5-99cc-a4be39959558",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [700, 3800]
},
{
"parameters": {
"content": "### Loose type checking",
"height": 1058.046875,
"width": 310.703125
},
"id": "cb382bde-1cba-4019-a45a-b50fbeb2f8ac",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [1180, 3804.375]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToNumber1",
"type": "number",
"value": "={{ $json.string.test2 }}"
},
{
"id": "2",
"name": "stringToNumber2",
"type": "number",
"value": "={{ $json.string.test3 }}"
},
{
"id": "3",
"name": "stringToNumber3",
"type": "number",
"value": "={{ $json.string.test9 }}"
},
{
"id": "4",
"name": "arrayToNumber1",
"type": "number",
"value": "={{ $json.array.test13 }}"
}
]
},
"options": {
"ignoreConversionErrors": true
}
},
"id": "d9c91c3d-de1e-430e-acb2-c832d1b41b21",
"name": "To Number1",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [1220, 3860]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToBoolean1",
"type": "boolean",
"value": "={{ $json.string.test5 }}"
},
{
"id": "2",
"name": "stringToBoolean2",
"type": "boolean",
"value": "=3,14"
},
{
"id": "3",
"name": "stringToBoolean3",
"type": "boolean",
"value": "={{ $json.string.test7 }}"
},
{
"id": "4",
"name": "stringToBoolean4",
"type": "boolean",
"value": "={{ $json.string.test11 }}"
},
{
"id": "5",
"name": "stringToBoolean5",
"type": "boolean",
"value": "={{ $json.string.test12 }}"
},
{
"id": "6",
"name": "stringToBoolean6",
"type": "boolean",
"value": "={{ $json.string.test17 }}"
},
{
"id": "7",
"name": "numberToBoolean1",
"type": "boolean",
"value": "={{ $json.number.test1 }}"
},
{
"id": "8",
"name": "numberToBoolean2",
"type": "boolean",
"value": "={{ $json.number.test4 }}"
}
]
},
"options": {
"ignoreConversionErrors": true
}
},
"id": "2a62319a-9850-4aed-ba83-f7e1fae233d6",
"name": "To Boolean1",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [1220, 4060]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToArray1",
"type": "array",
"value": "={{ $json.string.test2 }}"
},
{
"id": "2",
"name": "stringToArray2",
"type": "array",
"value": "={{ $json.string.test5 }}"
}
]
},
"options": {
"ignoreConversionErrors": true
}
},
"id": "72275d21-9a12-4030-98b9-4a8ef37e0158",
"name": "To Array1",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [1220, 4240]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1",
"name": "stringToObject1",
"type": "object",
"value": "={{ $json.string.test14 }}"
},
{
"id": "2",
"name": "stringToObject2",
"type": "object",
"value": "={{ $json.string.test15 }}"
}
]
},
"options": {
"ignoreConversionErrors": true
}
},
"id": "c6b117f1-44b9-41ef-ad26-b8c77e37ed9e",
"name": "To Object1",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [1220, 4440]
},
{
"parameters": {},
"id": "8e3ce059-9c1a-4490-b5a8-6cfb22e43632",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [720, 3460]
},
{
"parameters": {},
"id": "e581a88a-900e-4d9a-9dcd-6a4b6e30c39a",
"name": "No Operation, do nothing1",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [980, 3460]
},
{
"parameters": {
"content": "### Keep Input Fields",
"height": 752.046875,
"width": 310.703125
},
"id": "e03d8297-9eed-4679-9a8a-fc3e004ec0c7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [700, 4940]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "c42efef4-240d-42b8-baf7-f9edc10a25ba",
"name": "test",
"value": "foo",
"type": "string"
}
]
},
"includeOtherFields": true,
"options": {}
},
"id": "cf0799c0-cf07-43f9-89ce-0d218f13f23f",
"name": "Keep All",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [800, 5000]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "ae431a73-282b-4547-b82a-f491ca244ad2",
"name": "test",
"value": "foo",
"type": "string"
}
]
},
"includeOtherFields": true,
"include": "selected",
"includeFields": "object, age",
"options": {}
},
"id": "90575fc8-502c-4a22-ba27-bcf13a73e71a",
"name": "Keep Selected",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [800, 5160]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "a1d28431-fd8e-4360-baec-f390515d57fd",
"name": "test",
"value": "foo",
"type": "string"
}
]
},
"includeOtherFields": true,
"include": "except",
"excludeFields": "age",
"options": {}
},
"id": "731be3d3-b08f-4e13-9f67-badae737d581",
"name": "Keep All Except",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [800, 5320]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "23c2d8eb-7326-43ae-80b0-e651611f5f43",
"name": "test",
"value": "foo",
"type": "string"
}
]
},
"options": {}
},
"id": "f310db17-beb9-436c-99ec-e0fa1deea94d",
"name": "Keep None",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [800, 5500]
},
{
"parameters": {
"jsCode": "return [{name: 'John Doe', age: 32, object: {nested: true}}, {name: 'Jane Doe', age: 35, object: {nested: true}}]"
},
"id": "7f9a81c4-5207-493f-bf48-9e52e4c350c6",
"name": "Code",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [480, 5240]
}
],
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
},
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "To String",
"type": "main",
"index": 0
},
{
"node": "To Number",
"type": "main",
"index": 0
},
{
"node": "To Boolean",
"type": "main",
"index": 0
},
{
"node": "To Array",
"type": "main",
"index": 0
},
{
"node": "To Object",
"type": "main",
"index": 0
},
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"No Operation, do nothing": {
"main": [
[
{
"node": "No Operation, do nothing1",
"type": "main",
"index": 0
}
]
]
},
"No Operation, do nothing1": {
"main": [
[
{
"node": "To Number1",
"type": "main",
"index": 0
},
{
"node": "To Boolean1",
"type": "main",
"index": 0
},
{
"node": "To Array1",
"type": "main",
"index": 0
},
{
"node": "To Object1",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Keep All",
"type": "main",
"index": 0
},
{
"node": "Keep Selected",
"type": "main",
"index": 0
},
{
"node": "Keep All Except",
"type": "main",
"index": 0
},
{
"node": "Keep None",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {
"To String": [
{
"json": {
"numberToString1": "52472",
"numberToString2": "-1",
"numberToString3": "1.334535",
"boolToString1": "true",
"boolToString2": "false",
"arrayToString1": "[1,2,3,4]",
"objectToString1": "{\"objKey\":2,\"objArray\":[1,2,3,4],\"objBool\":true}"
}
}
],
"To Number": [
{
"json": {
"stringToNumber1": 3,
"stringToNumber2": 3.14,
"boolToNumber1": 1,
"boolToNumber2": 0
}
}
],
"To Boolean": [
{
"json": {
"stringToBoolean1": true,
"stringToBoolean3": false,
"stringToBoolean4": true,
"stringToBoolean5": false,
"numberToBoolean1": false,
"numberToBoolean2": true
}
}
],
"To Array": [
{
"json": {
"stringToArray1": ["apples", "oranges"],
"stringToArray2": [1, 2],
"arrayToArray1": [1, 2, 3, 4]
}
}
],
"To Object": [
{
"json": {
"stringToObject1": {
"a": 1,
"b": {
"c": 10,
"d": "test"
}
},
"stringToObject2": {
"a": 1
}
}
}
],
"To Number1": [
{
"json": {
"stringToNumber1": "hello",
"stringToNumber2": 0,
"stringToNumber3": "false",
"arrayToNumber1": [1, 2, 3, 4]
}
}
],
"To Boolean1": [
{
"json": {
"stringToBoolean1": "3",
"stringToBoolean2": "3,14",
"stringToBoolean3": "3.14",
"stringToBoolean4": "[\"apples\", \"oranges\"]",
"stringToBoolean5": "\"apples\", \"oranges\"",
"stringToBoolean6": "undefined",
"numberToBoolean1": 52472,
"numberToBoolean2": 1.334535
}
}
],
"To Array1": [
{
"json": {
"stringToArray1": "hello",
"stringToArray2": "3"
}
}
],
"To Object1": [
{
"json": {
"stringToObject1": {
"a": 1,
"b": {
"c": 10,
"d": "test"
}
},
"stringToObject2": {
"a": 1
}
}
}
],
"Keep All": [
{
"json": {
"name": "John Doe",
"age": 32,
"object": {
"nested": true
},
"test": "foo"
}
},
{
"json": {
"name": "Jane Doe",
"age": 35,
"object": {
"nested": true
},
"test": "foo"
}
}
],
"Keep Selected": [
{
"json": {
"object": {
"nested": true
},
"age": 32,
"test": "foo"
}
},
{
"json": {
"object": {
"nested": true
},
"age": 35,
"test": "foo"
}
}
]
}
}

View File

@@ -181,11 +181,7 @@ describe('test Set2, parseJsonParameter', () => {
describe('test Set2, validateEntry', () => {
it('should convert number to string', () => {
const result = validateEntry(
{ name: 'foo', type: 'stringValue', stringValue: 42 as unknown as string },
node,
0,
);
const result = validateEntry('foo', 'string', 42 as unknown as string, node, 0);
expect(result).toEqual({
name: 'foo',
@@ -194,11 +190,7 @@ describe('test Set2, validateEntry', () => {
});
it('should convert array to string', () => {
const result = validateEntry(
{ name: 'foo', type: 'stringValue', stringValue: [1, 2, 3] as unknown as string },
node,
0,
);
const result = validateEntry('foo', 'string', [1, 2, 3] as unknown as string, node, 0);
expect(result).toEqual({
name: 'foo',
@@ -207,11 +199,7 @@ describe('test Set2, validateEntry', () => {
});
it('should convert object to string', () => {
const result = validateEntry(
{ name: 'foo', type: 'stringValue', stringValue: { foo: 'bar' } as unknown as string },
node,
0,
);
const result = validateEntry('foo', 'string', { foo: 'bar' } as unknown as string, node, 0);
expect(result).toEqual({
name: 'foo',
@@ -220,11 +208,7 @@ describe('test Set2, validateEntry', () => {
});
it('should convert boolean to string', () => {
const result = validateEntry(
{ name: 'foo', type: 'stringValue', stringValue: true as unknown as string },
node,
0,
);
const result = validateEntry('foo', 'string', true as unknown as string, node, 0);
expect(result).toEqual({
name: 'foo',
@@ -233,11 +217,7 @@ describe('test Set2, validateEntry', () => {
});
it('should convert undefined to string', () => {
const result = validateEntry(
{ name: 'foo', type: 'stringValue', stringValue: undefined as unknown as string },
node,
0,
);
const result = validateEntry('foo', 'string', undefined as unknown as string, node, 0);
expect(result).toEqual({
name: 'foo',

View File

@@ -21,7 +21,7 @@ const versionDescription: INodeTypeDescription = {
name: 'set',
icon: 'fa:pen',
group: ['input'],
version: [3, 3.1, 3.2],
version: [3, 3.1, 3.2, 3.3],
description: 'Modify, add, or remove item fields',
subtitle: '={{$parameter["mode"]}}',
defaults: {
@@ -44,7 +44,7 @@ const versionDescription: INodeTypeDescription = {
action: 'Edit item fields one by one',
},
{
name: 'JSON Output',
name: 'JSON',
value: 'raw',
description: 'Customize item output with JSON',
action: 'Customize item output with JSON',
@@ -96,6 +96,11 @@ const versionDescription: INodeTypeDescription = {
type: 'options',
description: 'How to select the fields you want to include in your output items',
default: 'all',
displayOptions: {
show: {
'@version': [3, 3.1, 3.2],
},
},
options: [
{
name: 'All Input Fields',
@@ -119,6 +124,49 @@ const versionDescription: INodeTypeDescription = {
},
],
},
{
displayName: 'Include Other Input Fields',
name: 'includeOtherFields',
type: 'boolean',
default: false,
description:
"Whether to pass to the output all the input fields (along with the fields set in 'Fields to Set')",
displayOptions: {
hide: {
'@version': [3, 3.1, 3.2],
},
},
},
{
displayName: 'Input Fields to Include',
name: 'include',
type: 'options',
description: 'How to select the fields you want to include in your output items',
default: 'all',
displayOptions: {
hide: {
'@version': [3, 3.1, 3.2],
'/includeOtherFields': [false],
},
},
options: [
{
name: 'All',
value: INCLUDE.ALL,
description: 'Also include all unchanged fields from the input',
},
{
name: 'Selected',
value: INCLUDE.SELECTED,
description: 'Also include the fields listed in the parameter “Fields to Include”',
},
{
name: 'All Except',
value: INCLUDE.EXCEPT,
description: 'Exclude the fields listed in the parameter “Fields to Exclude”',
},
],
},
{
displayName: 'Fields to Include',
name: 'includeFields',
@@ -232,11 +280,16 @@ export class SetV2 implements INodeType {
}
for (let i = 0; i < items.length; i++) {
const include = this.getNodeParameter('include', i) as IncludeMods;
const includeOtherFields = this.getNodeParameter('includeOtherFields', i, false) as boolean;
const include = this.getNodeParameter('include', i, 'all') as IncludeMods;
const options = this.getNodeParameter('options', i, {});
const node = this.getNode();
options.include = include;
if (node.typeVersion >= 3.3) {
options.include = includeOtherFields ? include : 'none';
} else {
options.include = include;
}
const newItem = await setNode[mode].execute.call(
this,

View File

@@ -17,6 +17,12 @@ export type SetField = {
objectValue?: string | IDataObject;
};
export type AssignmentSetField = {
name: string;
value: unknown;
type: string;
};
export const INCLUDE = {
ALL: 'all',
NONE: 'none',

View File

@@ -4,21 +4,22 @@ import type {
IExecuteFunctions,
INode,
INodeExecutionData,
ValidationResult,
} from 'n8n-workflow';
import {
deepCopy,
ApplicationError,
NodeOperationError,
deepCopy,
jsonParse,
validateFieldType,
ApplicationError,
} from 'n8n-workflow';
import set from 'lodash/set';
import get from 'lodash/get';
import set from 'lodash/set';
import unset from 'lodash/unset';
import { getResolvables, sanitazeDataPathKey } from '../../../../utils/utilities';
import type { SetNodeOptions, SetField } from './interfaces';
import type { SetNodeOptions } from './interfaces';
import { INCLUDE } from './interfaces';
const configureFieldHelper = (dotNotation?: boolean) => {
@@ -163,46 +164,43 @@ export const parseJsonParameter = (
};
export const validateEntry = (
entry: SetField,
name: string,
type: FieldType,
value: unknown,
node: INode,
itemIndex: number,
ignoreErrors = false,
nodeVersion?: number,
) => {
let entryValue = entry[entry.type];
const name = entry.name;
if (nodeVersion && nodeVersion >= 3.2 && (entryValue === undefined || entryValue === null)) {
if (nodeVersion && nodeVersion >= 3.2 && (value === undefined || value === null)) {
return { name, value: null };
}
const entryType = entry.type.replace('Value', '') as FieldType;
const description = `To fix the error try to change the type for the field "${name}" or activate the option “Ignore Type Conversion Errors” to apply a less strict type validation`;
if (entryType === 'string') {
if (nodeVersion && nodeVersion > 3 && (entryValue === undefined || entryValue === null)) {
if (type === 'string') {
if (nodeVersion && nodeVersion > 3 && (value === undefined || value === null)) {
if (ignoreErrors) {
return { name, value: null };
} else {
throw new NodeOperationError(
node,
`'${name}' expects a ${entryType} but we got '${String(entryValue)}' [item ${itemIndex}]`,
`'${name}' expects a ${type} but we got '${String(value)}' [item ${itemIndex}]`,
{ description },
);
}
} else if (typeof entryValue === 'object') {
entryValue = JSON.stringify(entryValue);
} else if (typeof value === 'object') {
value = JSON.stringify(value);
} else {
entryValue = String(entryValue);
value = String(value);
}
}
const validationResult = validateFieldType(name, entryValue, entryType);
const validationResult = validateFieldType(name, value, type);
if (!validationResult.valid) {
if (ignoreErrors) {
validationResult.newValue = entry[entry.type];
validationResult.newValue = value as ValidationResult['newValue'];
} else {
const message = `${validationResult.errorMessage} [item ${itemIndex}]`;
throw new NodeOperationError(node, message, {
@@ -212,9 +210,10 @@ export const validateEntry = (
}
}
const value = validationResult.newValue === undefined ? null : validationResult.newValue;
return { name, value };
return {
name,
value: validationResult.newValue === undefined ? null : validationResult.newValue,
};
};
export function resolveRawData(this: IExecuteFunctions, rawData: string, i: number) {

View File

@@ -1,4 +1,6 @@
import type {
AssignmentCollectionValue,
FieldType,
IDataObject,
IExecuteFunctions,
INode,
@@ -23,6 +25,11 @@ const properties: INodeProperties[] = [
placeholder: 'Add Field',
type: 'fixedCollection',
description: 'Edit existing fields or add new ones to modify the output data',
displayOptions: {
show: {
'@version': [3, 3.1, 3.2],
},
},
typeOptions: {
multipleValues: true,
sortable: true,
@@ -156,6 +163,17 @@ const properties: INodeProperties[] = [
},
],
},
{
displayName: 'Fields to Set',
name: 'assignments',
type: 'assignmentCollection',
displayOptions: {
hide: {
'@version': [3, 3.1, 3.2],
},
},
default: {},
},
];
const displayOptions = {
@@ -175,35 +193,60 @@ export async function execute(
node: INode,
) {
try {
const fields = this.getNodeParameter('fields.values', i, []) as SetField[];
if (node.typeVersion < 3.3) {
const fields = this.getNodeParameter('fields.values', i, []) as SetField[];
const newData: IDataObject = {};
const newData: IDataObject = {};
for (const entry of fields) {
if (
entry.type === 'objectValue' &&
rawFieldsData[entry.name] !== undefined &&
entry.objectValue !== undefined &&
entry.objectValue !== null
) {
entry.objectValue = parseJsonParameter(
resolveRawData.call(this, rawFieldsData[entry.name] as string, i),
for (const entry of fields) {
if (
entry.type === 'objectValue' &&
rawFieldsData[entry.name] !== undefined &&
entry.objectValue !== undefined &&
entry.objectValue !== null
) {
entry.objectValue = parseJsonParameter(
resolveRawData.call(this, rawFieldsData[entry.name] as string, i),
node,
i,
entry.name,
);
}
const { name, value } = validateEntry(
entry.name,
entry.type.replace('Value', '') as FieldType,
entry[entry.type],
node,
i,
entry.name,
options.ignoreConversionErrors,
node.typeVersion,
);
newData[name] = value;
}
const { name, value } = validateEntry(
entry,
node,
i,
options.ignoreConversionErrors,
node.typeVersion,
);
newData[name] = value;
return composeReturnItem.call(this, i, item, newData, options);
}
const assignmentCollection = this.getNodeParameter(
'assignments',
i,
) as AssignmentCollectionValue;
const newData = Object.fromEntries(
(assignmentCollection?.assignments ?? []).map((assignment) => {
const { name, value } = validateEntry(
assignment.name,
assignment.type as FieldType,
assignment.value,
node,
i,
options.ignoreConversionErrors,
node.typeVersion,
);
return [name, value];
}),
);
return composeReturnItem.call(this, i, item, newData, options);
} catch (error) {
if (this.continueOnFail()) {

View File

@@ -13,7 +13,7 @@ import type { SetNodeOptions } from './helpers/interfaces';
const properties: INodeProperties[] = [
{
displayName: 'JSON Output',
displayName: 'JSON',
name: 'jsonOutput',
type: 'json',
typeOptions: {