2023-09-19 03:16:35 -07:00
/* eslint-disable n8n-nodes-base/node-filename-against-convention */
import type {
IDataObject ,
IExecuteFunctions ,
INodeExecutionData ,
INodeType ,
INodeTypeBaseDescription ,
INodeTypeDescription ,
} from 'n8n-workflow' ;
import type { IncludeMods , SetField , SetNodeOptions } from './helpers/interfaces' ;
import { INCLUDE } from './helpers/interfaces' ;
import * as raw from './raw.mode' ;
import * as manual from './manual.mode' ;
type Mode = 'manual' | 'raw' ;
const versionDescription : INodeTypeDescription = {
displayName : 'Edit Fields (Set)' ,
name : 'set' ,
icon : 'fa:pen' ,
group : [ 'input' ] ,
2024-02-06 09:34:34 -08:00
version : [ 3 , 3.1 , 3.2 , 3.3 ] ,
2023-12-08 02:40:05 -08:00
description : 'Modify, add, or remove item fields' ,
2023-09-19 03:16:35 -07:00
subtitle : '={{$parameter["mode"]}}' ,
defaults : {
name : 'Edit Fields' ,
color : '#0000FF' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
properties : [
{
displayName : 'Mode' ,
name : 'mode' ,
type : 'options' ,
noDataExpression : true ,
options : [
{
name : 'Manual Mapping' ,
value : 'manual' ,
description : 'Edit item fields one by one' ,
action : 'Edit item fields one by one' ,
} ,
{
2024-02-06 09:34:34 -08:00
name : 'JSON' ,
2023-09-19 03:16:35 -07:00
value : 'raw' ,
description : 'Customize item output with JSON' ,
action : 'Customize item output with JSON' ,
} ,
] ,
default : 'manual' ,
} ,
{
displayName : 'Duplicate Item' ,
name : 'duplicateItem' ,
type : 'boolean' ,
default : false ,
isNodeSetting : true ,
} ,
{
displayName : 'Duplicate Item Count' ,
name : 'duplicateCount' ,
type : 'number' ,
default : 0 ,
typeOptions : {
minValue : 0 ,
} ,
description :
'How many times the item should be duplicated, mainly used for testing and debugging' ,
isNodeSetting : true ,
displayOptions : {
show : {
duplicateItem : [ true ] ,
} ,
} ,
} ,
{
displayName :
'Item duplication is set in the node settings. This option will be ignored when the workflow runs automatically.' ,
name : 'duplicateWarning' ,
type : 'notice' ,
default : '' ,
displayOptions : {
show : {
duplicateItem : [ true ] ,
} ,
} ,
} ,
. . . raw . description ,
. . . manual . description ,
{
displayName : 'Include in Output' ,
name : 'include' ,
type : 'options' ,
description : 'How to select the fields you want to include in your output items' ,
default : 'all' ,
2024-02-06 09:34:34 -08:00
displayOptions : {
show : {
'@version' : [ 3 , 3.1 , 3.2 ] ,
} ,
} ,
2023-09-19 03:16:35 -07:00
options : [
{
name : 'All Input Fields' ,
value : INCLUDE.ALL ,
description : 'Also include all unchanged fields from the input' ,
} ,
{
name : 'No Input Fields' ,
value : INCLUDE.NONE ,
description : 'Include only the fields specified above' ,
} ,
{
name : 'Selected Input Fields' ,
value : INCLUDE.SELECTED ,
description : 'Also include the fields listed in the parameter “Fields to Include”' ,
} ,
{
name : 'All Input Fields Except' ,
value : INCLUDE.EXCEPT ,
description : 'Exclude the fields listed in the parameter “Fields to Exclude”' ,
} ,
] ,
} ,
2024-02-06 09:34:34 -08:00
{
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”' ,
} ,
] ,
} ,
2023-09-19 03:16:35 -07:00
{
displayName : 'Fields to Include' ,
name : 'includeFields' ,
type : 'string' ,
default : '' ,
placeholder : 'e.g. fieldToInclude1,fieldToInclude2' ,
description :
'Comma-separated list of the field names you want to include in the output. You can drag the selected fields from the input panel.' ,
requiresDataPath : 'multiple' ,
displayOptions : {
show : {
include : [ 'selected' ] ,
} ,
} ,
} ,
{
displayName : 'Fields to Exclude' ,
name : 'excludeFields' ,
type : 'string' ,
default : '' ,
placeholder : 'e.g. fieldToExclude1,fieldToExclude2' ,
description :
'Comma-separated list of the field names you want to exclude from the output. You can drag the selected fields from the input panel.' ,
requiresDataPath : 'multiple' ,
displayOptions : {
show : {
include : [ 'except' ] ,
} ,
} ,
} ,
{
displayName : 'Options' ,
name : 'options' ,
type : 'collection' ,
placeholder : 'Add Option' ,
default : { } ,
options : [
{
2024-01-03 03:08:16 -08:00
displayName : 'Include Binary File' ,
2023-09-19 03:16:35 -07:00
name : 'includeBinary' ,
type : 'boolean' ,
default : true ,
description : 'Whether binary data should be included if present in the input item' ,
} ,
{
displayName : 'Ignore Type Conversion Errors' ,
name : 'ignoreConversionErrors' ,
type : 'boolean' ,
default : false ,
description :
'Whether to ignore field type errors and apply a less strict type conversion' ,
displayOptions : {
show : {
'/mode' : [ 'manual' ] ,
} ,
} ,
} ,
{
displayName : 'Support Dot Notation' ,
name : 'dotNotation' ,
type : 'boolean' ,
default : true ,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description :
'By default, dot-notation is used in property names. This means that "a.b" will set the property "b" underneath "a" so { "a": { "b": value} }. If that is not intended this can be deactivated, it will then set { "a.b": value } instead.' ,
} ,
] ,
} ,
] ,
} ;
export class SetV2 implements INodeType {
description : INodeTypeDescription ;
constructor ( baseDescription : INodeTypeBaseDescription ) {
this . description = {
. . . baseDescription ,
. . . versionDescription ,
} ;
}
async execute ( this : IExecuteFunctions ) {
const items = this . getInputData ( ) ;
const mode = this . getNodeParameter ( 'mode' , 0 ) as Mode ;
const duplicateItem = this . getNodeParameter ( 'duplicateItem' , 0 , false ) as boolean ;
const setNode = { raw , manual } ;
const returnData : INodeExecutionData [ ] = [ ] ;
const rawData : IDataObject = { } ;
if ( mode === 'raw' ) {
const jsonOutput = this . getNodeParameter ( 'jsonOutput' , 0 , '' , {
rawExpressions : true ,
} ) as string | undefined ;
if ( jsonOutput ? . startsWith ( '=' ) ) {
rawData . jsonOutput = jsonOutput . replace ( /^=+/ , '' ) ;
}
} else {
const workflowFieldsJson = this . getNodeParameter ( 'fields.values' , 0 , [ ] , {
rawExpressions : true ,
} ) as SetField [ ] ;
for ( const entry of workflowFieldsJson ) {
if ( entry . type === 'objectValue' && ( entry . objectValue as string ) . startsWith ( '=' ) ) {
rawData [ entry . name ] = ( entry . objectValue as string ) . replace ( /^=+/ , '' ) ;
}
}
}
for ( let i = 0 ; i < items . length ; i ++ ) {
2024-02-06 09:34:34 -08:00
const includeOtherFields = this . getNodeParameter ( 'includeOtherFields' , i , false ) as boolean ;
const include = this . getNodeParameter ( 'include' , i , 'all' ) as IncludeMods ;
2023-09-19 03:16:35 -07:00
const options = this . getNodeParameter ( 'options' , i , { } ) ;
const node = this . getNode ( ) ;
2024-02-06 09:34:34 -08:00
if ( node . typeVersion >= 3.3 ) {
options . include = includeOtherFields ? include : 'none' ;
} else {
options . include = include ;
}
2023-09-19 03:16:35 -07:00
const newItem = await setNode [ mode ] . execute . call (
this ,
items [ i ] ,
i ,
options as SetNodeOptions ,
rawData ,
node ,
) ;
if ( duplicateItem && this . getMode ( ) === 'manual' ) {
const duplicateCount = this . getNodeParameter ( 'duplicateCount' , 0 , 0 ) as number ;
for ( let j = 0 ; j <= duplicateCount ; j ++ ) {
returnData . push ( newItem ) ;
}
} else {
returnData . push ( newItem ) ;
}
}
return [ returnData ] ;
}
}