2021-02-07 08:38:37 -08:00
import {
IExecuteFunctions ,
} from 'n8n-core' ;
import {
IDataObject ,
INodeExecutionData ,
INodeType ,
INodeTypeDescription ,
2021-04-16 09:33:36 -07:00
NodeOperationError ,
2021-02-07 08:38:37 -08:00
} from 'n8n-workflow' ;
import {
apiRequest ,
apiRequestAllItems ,
IRecord ,
} from './GenericFunction' ;
export class Stackby implements INodeType {
description : INodeTypeDescription = {
displayName : 'Stackby' ,
name : 'stackby' ,
icon : 'file:stackby.png' ,
group : [ 'transform' ] ,
version : 1 ,
2021-07-03 05:40:16 -07:00
description : 'Read, write, and delete data in Stackby' ,
2021-02-07 08:38:37 -08:00
defaults : {
name : 'Stackby' ,
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'stackbyApi' ,
required : true ,
} ,
] ,
properties : [
{
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
options : [
{
name : 'Append' ,
value : 'append' ,
} ,
{
name : 'Delete' ,
value : 'delete' ,
} ,
{
name : 'List' ,
value : 'list' ,
} ,
{
name : 'Read' ,
value : 'read' ,
} ,
] ,
default : 'append' ,
placeholder : 'Action to perform' ,
} ,
// ----------------------------------
// All
// ----------------------------------
{
displayName : 'Stack ID' ,
name : 'stackId' ,
type : 'string' ,
default : '' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The ID of the stack to access' ,
2021-02-07 08:38:37 -08:00
} ,
{
displayName : 'Table' ,
name : 'table' ,
type : 'string' ,
default : '' ,
placeholder : 'Stories' ,
required : true ,
description : 'Enter Table Name' ,
} ,
// ----------------------------------
// read
// ----------------------------------
{
displayName : 'ID' ,
name : 'id' ,
type : 'string' ,
displayOptions : {
show : {
operation : [
'read' ,
'delete' ,
] ,
} ,
} ,
default : '' ,
required : true ,
2022-05-06 14:01:25 -07:00
description : 'ID of the record to return' ,
2021-02-07 08:38:37 -08:00
} ,
// ----------------------------------
// list
// ----------------------------------
{
displayName : 'Return All' ,
name : 'returnAll' ,
type : 'boolean' ,
displayOptions : {
show : {
operation : [
'list' ,
] ,
} ,
} ,
default : true ,
2022-05-06 14:01:25 -07:00
description : 'Whether to return all results or only up to a given limit' ,
2021-02-07 08:38:37 -08:00
} ,
{
displayName : 'Limit' ,
name : 'limit' ,
type : 'number' ,
displayOptions : {
show : {
'operation' : [
'list' ,
] ,
'returnAll' : [
false ,
] ,
} ,
} ,
typeOptions : {
minValue : 1 ,
maxValue : 1000 ,
} ,
default : 1000 ,
2022-05-06 14:01:25 -07:00
description : 'Max number of results to return' ,
2021-02-07 08:38:37 -08:00
} ,
{
displayName : 'Additional Fields' ,
name : 'additionalFields' ,
type : 'collection' ,
displayOptions : {
show : {
operation : [
'list' ,
] ,
} ,
} ,
default : { } ,
placeholder : 'Add Field' ,
options : [
{
displayName : 'View' ,
name : 'view' ,
type : 'string' ,
default : '' ,
placeholder : 'All Stories' ,
2021-10-27 13:00:13 -07:00
description : 'The name or ID of a view in the Stories table. If set, only the records in that view will be returned. The records will be sorted according to the order of the view.' ,
2021-02-07 08:38:37 -08:00
} ,
] ,
} ,
// ----------------------------------
// append
// ----------------------------------
{
displayName : 'Columns' ,
name : 'columns' ,
type : 'string' ,
displayOptions : {
show : {
operation : [
'append' ,
] ,
} ,
} ,
default : '' ,
required : true ,
placeholder : 'id,name,description' ,
2022-05-06 14:01:25 -07:00
description : 'Comma-separated list of the properties which should used as columns for the new rows' ,
2021-02-07 08:38:37 -08:00
} ,
] ,
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
const returnData : IDataObject [ ] = [ ] ;
2022-04-22 09:29:51 -07:00
const length = items . length ;
2021-02-07 08:38:37 -08:00
let responseData ;
const qs : IDataObject = { } ;
const operation = this . getNodeParameter ( 'operation' , 0 ) as string ;
if ( operation === 'read' ) {
for ( let i = 0 ; i < length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
const stackId = this . getNodeParameter ( 'stackId' , i ) as string ;
const table = encodeURI ( this . getNodeParameter ( 'table' , i ) as string ) ;
const rowIds = this . getNodeParameter ( 'id' , i ) as string ;
qs . rowIds = [ rowIds ] ;
responseData = await apiRequest . call ( this , 'GET' , ` /rowlist/ ${ stackId } / ${ table } ` , { } , qs ) ;
// tslint:disable-next-line: no-any
returnData . push . apply ( returnData , responseData . map ( ( data : any ) = > data . field ) ) ;
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
continue ;
}
throw error ;
}
2021-02-07 08:38:37 -08:00
}
}
if ( operation === 'delete' ) {
for ( let i = 0 ; i < length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
const stackId = this . getNodeParameter ( 'stackId' , i ) as string ;
const table = encodeURI ( this . getNodeParameter ( 'table' , i ) as string ) ;
const rowIds = this . getNodeParameter ( 'id' , i ) as string ;
qs . rowIds = [ rowIds ] ;
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
responseData = await apiRequest . call ( this , 'DELETE' , ` /rowdelete/ ${ stackId } / ${ table } ` , { } , qs ) ;
responseData = responseData . records ;
returnData . push . apply ( returnData , responseData ) ;
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
continue ;
}
throw error ;
}
2021-02-07 08:38:37 -08:00
}
}
if ( operation === 'append' ) {
2021-07-19 23:58:54 -07:00
try {
const records : { [ key : string ] : IRecord [ ] } = { } ;
let key = '' ;
for ( let i = 0 ; i < length ; i ++ ) {
const stackId = this . getNodeParameter ( 'stackId' , i ) as string ;
const table = encodeURI ( this . getNodeParameter ( 'table' , i ) as string ) ;
const columns = this . getNodeParameter ( 'columns' , i ) as string ;
const columnList = columns . split ( ',' ) . map ( column = > column . trim ( ) ) ;
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
// tslint:disable-next-line: no-any
const record : { [ key : string ] : any } = { } ;
for ( const column of columnList ) {
if ( items [ i ] . json [ column ] === undefined ) {
throw new NodeOperationError ( this . getNode ( ) , ` Column ${ column } does not exist on input ` ) ;
} else {
record [ column ] = items [ i ] . json [ column ] ;
}
}
key = ` ${ stackId } / ${ table } ` ;
if ( records [ key ] === undefined ) {
records [ key ] = [ ] ;
2021-02-07 08:38:37 -08:00
}
2021-07-19 23:58:54 -07:00
records [ key ] . push ( { field : record } ) ;
2021-02-07 08:38:37 -08:00
}
2021-07-19 23:58:54 -07:00
for ( const key of Object . keys ( records ) ) {
responseData = await apiRequest . call ( this , 'POST' , ` /rowcreate/ ${ key } ` , { records : records [ key ] } ) ;
2021-02-07 08:38:37 -08:00
}
2021-07-19 23:58:54 -07:00
// tslint:disable-next-line: no-any
returnData . push . apply ( returnData , responseData . map ( ( data : any ) = > data . field ) ) ;
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
} else {
throw error ;
}
2021-02-07 08:38:37 -08:00
}
}
if ( operation === 'list' ) {
for ( let i = 0 ; i < length ; i ++ ) {
2021-07-19 23:58:54 -07:00
try {
const stackId = this . getNodeParameter ( 'stackId' , i ) as string ;
const table = encodeURI ( this . getNodeParameter ( 'table' , i ) as string ) ;
const returnAll = this . getNodeParameter ( 'returnAll' , 0 ) as boolean ;
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
const additionalFields = this . getNodeParameter ( 'additionalFields' , i , { } ) as IDataObject ;
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
if ( additionalFields . view ) {
qs . view = additionalFields . view ;
}
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
if ( returnAll === true ) {
responseData = await apiRequestAllItems . call ( this , 'GET' , ` /rowlist/ ${ stackId } / ${ table } ` , { } , qs ) ;
} else {
qs . maxrecord = this . getNodeParameter ( 'limit' , 0 ) as number ;
responseData = await apiRequest . call ( this , 'GET' , ` /rowlist/ ${ stackId } / ${ table } ` , { } , qs ) ;
}
2021-02-07 08:38:37 -08:00
2021-07-19 23:58:54 -07:00
// tslint:disable-next-line: no-any
returnData . push . apply ( returnData , responseData . map ( ( data : any ) = > data . field ) ) ;
} catch ( error ) {
if ( this . continueOnFail ( ) ) {
returnData . push ( { error : error.message } ) ;
continue ;
}
throw error ;
}
2021-02-07 08:38:37 -08:00
}
}
return [ this . helpers . returnJsonArray ( returnData ) ] ;
}
}