1- 2- 31import {
4- INodeType ,
5- INodeTypeDescription ,
2+ INodeType ,
3+ INodeTypeDescription ,
64 ILoadOptionsFunctions ,
75 INodeListSearchResult ,
86 IExecuteFunctions ,
@@ -17,22 +15,22 @@ import { apiRequest } from './GenericFunctions';
1715import isbot from 'isbot' ;
1816
1917interface LowcoderAppType {
20- applicationId : string ;
21- name : string ;
18+ applicationId : string ;
19+ name : string ;
2220 applicationType : number
2321}
2422
2523const WAIT_TIME_UNLIMITED = '3000年01月01日T00:00:00.000Z' ;
2624
2725export class Lowcoder implements INodeType {
28- description : INodeTypeDescription = {
26+ description : INodeTypeDescription = {
2927 displayName : 'Lowcoder' ,
3028 name : 'lowcoder' ,
3129 // eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
3230 icon : 'file:lowcoder.png' ,
3331 group : [ 'transform' ] ,
3432 version : 1 ,
35- subtitle : '=app:{{ $parameter["appId"]' ,
33+ subtitle : '=app:{{ $parameter["appId"]' ,
3634 description : 'Consume Lowcoder API' ,
3735 defaults : {
3836 name : 'Lowcoder' ,
@@ -50,100 +48,121 @@ export class Lowcoder implements INodeType {
5048 name : 'default' ,
5149 httpMethod : '={{$parameter["httpMethod"]}}' ,
5250 isFullPath : true ,
53- responseCode : '200' ,
5451 responseMode : 'onReceived' ,
55- responseData : 'allEntries ' ,
56- responseContentType : '={{$parameter["options"]["responseContentType"]}}' ,
52+ responseData : '={{$parameter["options"]["responseData"] || "Workflow Resumed!"}} ' ,
53+ responseContentType : '={{$parameter["options"]["responseContentType"] || "application/json" }}' ,
5754 responsePropertyName : '={{$parameter["options"]["responsePropertyName"]}}' ,
5855 responseHeaders : '={{$parameter["options"]["responseHeaders"]}}' ,
5956 path : '={{$parameter["appId"] || ""}}' ,
60- restartWebhook : true ,
57+ restartWebhook : true ,
6158 } ,
62- ] ,
59+ ] ,
6360 properties : [
6461 ...appFields ,
6562 {
66- displayName : 'Resume the workflow by calling this Webhook: http(s)://{n8n-url}/webhook-waiting/{Workflow-Execution-ID}/{Lowcoder-App-ID}' ,
67- name : 'webhookNotice' ,
68- type : 'notice' ,
69- default : '' ,
70- } ,
71- {
72- displayName : 'The Workflow-Execution-ID is available via the n8n Rest API' ,
73- name : 'webhookNotice' ,
74- type : 'notice' ,
75- default : '' ,
76- } ,
63+ displayName : 'Resume the workflow by calling this Webhook: http(s)://{n8n-url}/webhook-waiting/{Workflow-Execution-ID}/{Lowcoder-App-ID}' ,
64+ name : 'webhookNotice' ,
65+ type : 'notice' ,
66+ default : '' ,
67+ } ,
68+ {
69+ displayName : 'The Workflow-Execution-ID is available via the n8n Rest API' ,
70+ name : 'webhookNotice' ,
71+ type : 'notice' ,
72+ default : '' ,
73+ } ,
7774 httpMethodsProperty ,
78- optionsProperty
75+ optionsProperty ,
76+ {
77+ displayName : 'Response Code' ,
78+ name : 'responseCode' ,
79+ type : 'number' ,
80+ default : 200 ,
81+ description : 'The HTTP response code to return' ,
82+ } ,
7983 ] ,
80- } ;
84+ } ;
8185
8286 methods = {
83- listSearch : {
84- async searchApps (
85- this : ILoadOptionsFunctions ,
86- query ?: string ,
87- ) : Promise < INodeListSearchResult > {
88- 89- const searchResults = await apiRequest . call (
90- this ,
91- 'GET' ,
92- 'applications/list' ,
93- { } ,
94- {
95- query,
87+ listSearch : {
88+ async searchApps (
89+ this : ILoadOptionsFunctions ,
90+ query ?: string ,
91+ ) : Promise < INodeListSearchResult > {
92+ const searchResults = await apiRequest . call (
93+ this ,
94+ 'GET' ,
95+ 'applications/list' ,
96+ { } ,
97+ {
98+ query,
9699 withContainerSize : false
97- } ,
98- ) ;
99- console . log ( searchResults ) ;
100- return {
101- results : searchResults . data . map ( ( b : LowcoderAppType ) => ( {
102- name : `${ b . name } (${ b . applicationType == 2 ? "Module" : "App" } )` ,
103- value : b . applicationId ,
104- } ) ) ,
105- } ;
106- } ,
107- } ,
108- } ;
100+ } ,
101+ ) ;
102+ console . log ( searchResults ) ;
103+ return {
104+ results : searchResults . data . map ( ( b : LowcoderAppType ) => ( {
105+ name : `${ b . name } (${ b . applicationType == 2 ? "Module" : "App" } )` ,
106+ value : b . applicationId ,
107+ } ) ) ,
108+ } ;
109+ } ,
110+ } ,
111+ } ;
109112
110113 async webhook ( this : IWebhookFunctions ) : Promise < IWebhookResponseData > {
111- const options = this . getNodeParameter ( 'options' , { } ) as {
112- binaryData : boolean ;
113- ignoreBots : boolean ;
114- rawBody : Buffer ;
115- responseData ?: string ;
116- } ;
117- const req = this . getRequestObject ( ) ;
118- const resp = this . getResponseObject ( ) ;
114+ const options = this . getNodeParameter ( 'options' , { } ) as {
115+ binaryData : boolean ;
116+ ignoreBots : boolean ;
117+ rawBody : Buffer ;
118+ responseData ?: string ;
119+ responseCode ?: number ;
120+ } ;
121+ const req = this . getRequestObject ( ) ;
122+ const resp = this . getResponseObject ( ) ;
119123
120- try {
121- if ( options . ignoreBots && isbot ( req . headers [ 'user-agent' ] ) ) {
122- throw new NodeApiError ( this . getNode ( ) , { } , { message : 'Authorization data is wrong!' } ) ;
124+ try {
125+ if ( options . ignoreBots && isbot ( req . headers [ 'user-agent' ] ) ) {
126+ throw new NodeApiError ( this . getNode ( ) , { } , { message : 'Authorization data is wrong!' } ) ;
123127 }
124- } catch ( error ) {
125- resp . writeHead ( error . responseCode , { 'WWW-Authenticate' : 'Basic realm="Webhook"' } ) ;
128+ } catch ( error ) {
129+ resp . writeHead ( error . responseCode || 401 , { 'WWW-Authenticate' : 'Basic realm="Webhook"' } ) ;
126130 resp . end ( error . message ) ;
127131 return { noWebhookResponse : true } ;
128- }
129- const body = typeof req . body != 'undefined' ? req . body : { } ;
130- const returnItem : INodeExecutionData = {
131- binary : { } ,
132- json : {
133- headers : req . headers ,
134- params : req . params ,
135- query : req . query ,
136- body : body ,
137- } ,
138- } ;
139- return { workflowData : [ [ returnItem ] ] } ;
140- }
132+ }
141133
142- async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
134+ const type = req . query . type ;
135+ if ( type === 'resume' ) {
136+ // Resume workflow as before
137+ const body = typeof req . body != 'undefined' ? req . body : { } ;
138+ const returnItem : INodeExecutionData = {
139+ binary : { } ,
140+ json : {
141+ headers : req . headers ,
142+ params : req . params ,
143+ query : req . query ,
144+ body : body ,
145+ } ,
146+ } ;
147+ const responseCode = options . responseCode || 200 ;
148+ resp . statusCode = responseCode ;
149+ return { workflowData : [ [ returnItem ] ] } ;
150+ } else {
151+ // Return input data, and don't resume
152+ const staticData = this . getWorkflowStaticData ( 'node' ) ;
153+ const previousData = staticData . previousNodeData || [ ] ;
154+ resp . statusCode = 200 ;
155+ resp . setHeader ( 'Content-Type' , 'application/json' ) ;
156+ resp . end ( JSON . stringify ( { message : 'Static response: workflow not resumed' , type, previousData } ) ) ;
157+ return { noWebhookResponse : true } ;
158+ }
159+ }
143160
161+ async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
144162 let waitTill = new Date ( WAIT_TIME_UNLIMITED ) ;
145- 163+ const staticData = this . getWorkflowStaticData ( 'node' ) ;
164+ staticData . previousNodeData = this . getInputData ( ) . map ( item => item . json ) ;
146165 await this . putExecutionToWait ( waitTill ) ;
147- return [ this . getInputData ( ) ] ;
148- }
166+ return [ this . getInputData ( ) ] ;
167+ }
149168}
0 commit comments