2019-06-23 03:35:23 -07:00
import { IExecuteFunctions } from 'n8n-core' ;
import {
INodeExecutionData ,
INodeType ,
INodeTypeDescription ,
} from 'n8n-workflow' ;
import {
get ,
set ,
unset ,
} from 'lodash' ;
interface IRenameKey {
currentKey : string ;
newKey : string ;
}
export class RenameKeys implements INodeType {
description : INodeTypeDescription = {
displayName : 'Rename Keys' ,
name : 'renameKeys' ,
2019-07-26 02:27:46 -07:00
icon : 'fa:edit' ,
2019-06-23 03:35:23 -07:00
group : [ 'transform' ] ,
version : 1 ,
description : 'Renames keys.' ,
defaults : {
name : 'Rename Keys' ,
color : '#772244' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
properties : [
{
displayName : 'Keys' ,
name : 'keys' ,
placeholder : 'Add new key' ,
description : 'Adds a key which should be renamed.' ,
type : 'fixedCollection' ,
typeOptions : {
multipleValues : true ,
} ,
default : { } ,
options : [
{
displayName : 'Key' ,
name : 'key' ,
values : [
{
displayName : 'Current Key Name' ,
name : 'currentKey' ,
type : 'string' ,
default : '' ,
placeholder : 'currentKey' ,
description : 'The current name of the key. It is also possible to define deep keys by using dot-notation like for example: "level1.level2.currentKey"' ,
} ,
{
displayName : 'New Key Name' ,
name : 'newKey' ,
type : 'string' ,
default : '' ,
placeholder : 'newKey' ,
description : 'the name the key should be renamed to. It is also possible to define deep keys by using dot-notation like for example: "level1.level2.newKey"' ,
} ,
2020-10-22 06:46:03 -07:00
] ,
2019-06-23 03:35:23 -07:00
} ,
] ,
2020-10-22 06:46:03 -07:00
} ,
] ,
2019-06-23 03:35:23 -07:00
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
2019-08-01 13:55:33 -07:00
const returnData : INodeExecutionData [ ] = [ ] ;
2019-06-23 03:35:23 -07:00
let item : INodeExecutionData ;
2019-08-01 13:55:33 -07:00
let newItem : INodeExecutionData ;
2019-06-23 03:35:23 -07:00
let renameKeys : IRenameKey [ ] ;
let value : any ; // tslint:disable-line:no-any
for ( let itemIndex = 0 ; itemIndex < items . length ; itemIndex ++ ) {
renameKeys = this . getNodeParameter ( 'keys.key' , itemIndex , [ ] ) as IRenameKey [ ] ;
item = items [ itemIndex ] ;
2019-08-01 13:55:33 -07:00
// Copy the whole JSON data as data on any level can be renamed
newItem = {
json : JSON.parse ( JSON . stringify ( item . json ) ) ,
} ;
if ( item . binary !== undefined ) {
// Reference binary data if any exists. We can reference it
// as this nodes does not change it
newItem . binary = item . binary ;
}
2019-06-23 03:35:23 -07:00
renameKeys . forEach ( ( renameKey ) = > {
2021-01-07 04:42:05 -08:00
if ( renameKey . currentKey === '' || renameKey . newKey === '' || renameKey . currentKey === renameKey . newKey ) {
// Ignore all which do not have all the values set or if the new key is equal to the current key
2019-06-23 03:35:23 -07:00
return ;
}
value = get ( item . json , renameKey . currentKey as string ) ;
if ( value === undefined ) {
return ;
}
2019-08-01 13:55:33 -07:00
set ( newItem . json , renameKey . newKey , value ) ;
2019-06-23 03:35:23 -07:00
2019-08-01 13:55:33 -07:00
unset ( newItem . json , renameKey . currentKey as string ) ;
2019-06-23 03:35:23 -07:00
} ) ;
2019-08-01 13:55:33 -07:00
returnData . push ( newItem ) ;
2019-06-23 03:35:23 -07:00
}
2019-08-01 13:55:33 -07:00
return [ returnData ] ;
2019-06-23 03:35:23 -07:00
}
}