1- import Operators from '../constants/operators.js' ;
2-
31// assumption is that apis are giving json as output
42
3+ import { computeEvaluateNode } from './compute/evaluatenode' ;
4+ import { computeRequestNode } from './compute/requestnode' ;
5+
56class Graph {
6- constructor ( nodes , edges , onGraphComplete , authKey , runRequest ) {
7+ constructor ( nodes , edges , onGraphComplete ) {
78 this . nodes = nodes ;
89 this . edges = edges ;
910 this . onGraphComplete = onGraphComplete ;
10- this . authKey = authKey ;
11- this . runRequest = runRequest ;
1211 this . logs = [ ] ;
1312 this . timeout = 60000 ; // 1m timeout
1413 this . startTime = Date . now ( ) ;
1514 this . graphRunNodeOutput = { } ;
15+ this . auth = undefined ;
1616 }
1717
1818 #checkTimeout( ) {
1919 return Date . now ( ) - this . startTime > this . timeout ;
2020 }
2121
22- #formulateRequest( node , finalUrl ) {
23- let restMethod = node . data . requestType . toLowerCase ( ) ;
24- let contentType = 'application/json' ;
25- let requestData = undefined ;
26-
27- if ( restMethod === 'get' ) {
28- if ( node . data . requestBody ) {
29- if ( node . data . requestBody . type === 'raw-json' ) {
30- contentType = 'application/json' ;
31- requestData = node . data . requestBody . body ? JSON . parse ( node . data . requestBody . body ) : JSON . parse ( '{}' ) ;
32- }
33- }
34- } else if ( restMethod === 'post' || restMethod === 'put' ) {
35- if ( node . data . requestBody ) {
36- if ( node . data . requestBody . type === 'form-data' ) {
37- contentType = 'multipart/form-data' ;
38- requestData = {
39- key : node . data . requestBody . body . key ,
40- value : node . data . requestBody . body . value ,
41- name : node . data . requestBody . body . name ,
42- } ;
43- } else if ( node . data . requestBody . type === 'raw-json' ) {
44- contentType = 'application/json' ;
45- requestData = node . data . requestBody . body ? JSON . parse ( node . data . requestBody . body ) : JSON . parse ( '{}' ) ;
46- }
47- }
48- }
49-
50- const options = {
51- method : restMethod ,
52- url : finalUrl ,
53- headers : {
54- 'Content-type' : contentType ,
55- } ,
56- data : requestData ,
57- auth : {
58- username : this . authKey ? this . authKey . accessId : '' ,
59- password : this . authKey ? this . authKey . accessKey : '' ,
60- } ,
61- } ;
62-
63- this . logs . push ( `${ restMethod } ${ finalUrl } ` ) ;
64- return options ;
65- }
66-
67- #computeNodeVariable( variable , prevNodeOutputData ) {
68- if ( variable . type . toLowerCase ( ) === 'string' ) {
69- return variable . value ;
70- }
71-
72- if ( variable . type . toLowerCase ( ) === 'number' ) {
73- return variable . value ;
74- }
75-
76- if ( variable . type . toLowerCase ( ) === 'bool' ) {
77- return Boolean ( variable . value ) ;
78- }
79-
80- if ( variable . type . toLowerCase ( ) === 'select' ) {
81- if ( prevNodeOutputData == undefined || Object . keys ( prevNodeOutputData ) . length === 0 ) {
82- this . logs . push (
83- `Cannot evaluate variable ${ variable } as previous node output data ${ JSON . stringify ( prevNodeOutputData ) } is empty` ,
84- ) ;
85- throw 'Error evaluating node variables' ;
86- }
87- const jsonTree = variable . value . split ( '.' ) ;
88- const getVal = ( parent , pos ) => {
89- if ( pos == jsonTree . length ) {
90- return parent ;
91- }
92- const key = jsonTree [ pos ] ;
93- if ( key == '' ) {
94- return parent ;
95- }
96-
97- return getVal ( parent [ key ] , pos + 1 ) ;
98- } ;
99- const result = getVal ( prevNodeOutputData , 0 ) ;
100- if ( result == undefined ) {
101- this . logs . push (
102- `Cannot evaluate variable ${ JSON . stringify ( variable ) } as previous node output data ${ JSON . stringify ( prevNodeOutputData ) } did not contain the variable` ,
103- ) ;
104- throw 'Error evaluating node variables' ;
105- }
106- return result ;
107- }
108- }
109-
110- #computeNodeVariables( variables , prevNodeOutputData ) {
111- let evalVariables = { } ;
112- Object . entries ( variables ) . map ( ( [ vname , variable ] , index ) => {
113- evalVariables [ vname ] = this . #computeNodeVariable( variable , prevNodeOutputData ) ;
114- } ) ;
115- return evalVariables ;
116- }
117-
118- async #computeRequestNode( node , prevNodeOutputData ) {
119- try {
120- // step1 evaluate variables of this node
121- const evalVariables = this . #computeNodeVariables( node . data . variables , prevNodeOutputData ) ;
122-
123- // step2 replace variables in url with value
124- let finalUrl = node . data . url ;
125- Object . entries ( evalVariables ) . map ( ( [ vname , vvalue ] , index ) => {
126- finalUrl = finalUrl . replace ( `{${ vname } }` , vvalue ) ;
127- } ) ;
128-
129- // step 3
130- const options = this . #formulateRequest( node , finalUrl ) ;
131-
132- console . debug ( 'Evaluated variables: ' , evalVariables ) ;
133- console . debug ( 'Evaluated Url: ' , finalUrl ) ;
134- //const res = await axios(options);
135- const res = await this . runRequest ( JSON . stringify ( options ) ) ;
136- this . logs . push ( `Request successful: ${ JSON . stringify ( res . data ) } ` ) ;
137- console . debug ( 'Response: ' , res ) ;
138- return [ 'Success' , node , res ] ;
139- } catch ( error ) {
140- console . debug ( 'Failure at node: ' , node ) ;
141- console . debug ( 'Error encountered: ' , error ) ;
142- if ( error . response ) {
143- // The request was made and the server responded with a status code
144- // that falls out of the range of 2xx
145- console . debug ( error . response . data ) ;
146- console . debug ( error . response . status ) ;
147- console . debug ( error . response . headers ) ;
148- this . logs . push (
149- `Request failed. Status: ${ error . response . status } , Data: ${ JSON . stringify ( error . response . data ) } ` ,
150- ) ;
151- } else if ( error . request ) {
152- // The request was made but no response was received
153- // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
154- // http.ClientRequest in node.js
155- console . debug ( 'Response: ' , error . request ) ;
156- this . logs . push ( `Request failed: ${ error . request } ` ) ;
157- } else if ( error . message ) {
158- // Something happened in setting up the request that triggered an Error
159- console . debug ( 'Response: ' , error . message ) ;
160- this . logs . push ( `Request failed: ${ error . message } ` ) ;
161- } else {
162- // Something not related to axios request
163- console . debug ( 'Failure: ' , error ) ;
164- this . logs . push ( `Request failed: ${ error } ` ) ;
165- }
166- return [ 'Failed' , node , error ] ;
167- }
168- }
169-
170- #computeEvaluateNode( node , prevNodeOutputData ) {
171- const evalVariables = this . #computeNodeVariables( node . data . variables , prevNodeOutputData ) ;
172- const var1 = evalVariables . var1 ;
173- const var2 = evalVariables . var2 ;
174-
175- const operator = node . data . operator ;
176- if ( operator == undefined ) {
177- throw 'Operator undefined' ;
178- }
179- this . logs . push (
180- `Evaluate var1: ${ JSON . stringify ( var1 ) } of type: ${ typeof var1 } , var2: ${ JSON . stringify ( var2 ) } of type: ${ typeof var2 } with operator: ${ operator } ` ,
181- ) ;
182- if ( operator == Operators . isEqualTo ) {
183- return var1 === var2 ;
184- } else if ( operator == Operators . isNotEqualTo ) {
185- return var1 != var2 ;
186- } else if ( operator == Operators . isGreaterThan ) {
187- return var1 > var2 ;
188- } else if ( operator == Operators . isLessThan ) {
189- return var1 < var2 ;
190- }
191- }
192-
19322 #computeConnectingEdge( node , result ) {
19423 let connectingEdge = undefined ;
19524
@@ -238,7 +67,7 @@ class Graph {
23867 }
23968
24069 if ( node . type === 'evaluateNode' ) {
241- if ( this . # computeEvaluateNode( node , prevNodeOutputData ) ) {
70+ if ( computeEvaluateNode ( node , prevNodeOutputData , this . logs ) ) {
24271 this . logs . push ( 'Result: true' ) ;
24372 result = [ 'Success' , node , prevNodeOutput , true ] ;
24473 } else {
@@ -257,8 +86,13 @@ class Graph {
25786 result = [ 'Success' , node , prevNodeOutput ] ;
25887 }
25988
89+ if ( node . type === 'authNode' ) {
90+ this . auth = node . data . auth ;
91+ result = [ 'Success' , node , prevNodeOutput ] ;
92+ }
93+
26094 if ( node . type === 'requestNode' ) {
261- result = await this . # computeRequestNode( node , prevNodeOutputData ) ;
95+ result = await computeRequestNode ( node , prevNodeOutputData , this . auth , this . logs ) ;
26296 }
26397
26498 if ( this . #checkTimeout( ) ) {
@@ -278,7 +112,7 @@ class Graph {
278112 if ( connectingEdge != undefined ) {
279113 const nextNode = this . nodes . find (
280114 ( node ) =>
281- [ 'requestNode' , 'outputNode' , 'evaluateNode' , 'delayNode' ] . includes ( node . type ) &&
115+ [ 'requestNode' , 'outputNode' , 'evaluateNode' , 'delayNode' , 'authNode' ] . includes ( node . type ) &&
282116 node . id === connectingEdge . target ,
283117 ) ;
284118 this . graphRunNodeOutput [ node . id ] = result [ 2 ] && result [ 2 ] . data ? result [ 2 ] . data : { } ;
@@ -298,7 +132,6 @@ class Graph {
298132 } ) ;
299133 this . graphRunNodeOutput = { } ;
300134
301- console . debug ( 'Using authkey: ' , this . authKey ) ;
302135 this . logs . push ( 'Start Flowtest' ) ;
303136 const startNode = this . nodes . find ( ( node ) => node . type === 'startNode' ) ;
304137 if ( startNode == undefined ) {
@@ -317,6 +150,7 @@ class Graph {
317150 }
318151 this . logs . push ( 'End Flowtest' ) ;
319152 this . logs . push ( `Total time: ${ Date . now ( ) - this . startTime } ms` ) ;
153+ console . log ( this . logs ) ;
320154 this . onGraphComplete ( result , this . logs ) ;
321155 } ) ;
322156 } else {
0 commit comments