11const fs = require ( 'fs' ) . promises ;
22const path = require ( 'path' ) ;
3+ const { URL } = require ( 'url' ) ;
34const vm = require ( 'vm' ) ;
45const Config = require ( "@cocreate/config" ) ;
5- const { URL } = require ( 'url' ) ;
6+ const { getValueFromObject } = require ( '@cocreate/utils' ) ;
7+
68
79class CoCreateLazyLoader {
810 constructor ( server , crud , files ) {
@@ -44,6 +46,7 @@ class CoCreateLazyLoader {
4446
4547 async request ( req , res ) {
4648 try {
49+ // TODO: track usage
4750 const valideUrl = new URL ( `http://${ req . headers . host } ${ req . url } ` ) ;
4851 const hostname = valideUrl . hostname ;
4952 let organization
@@ -211,21 +214,23 @@ class CoCreateLazyLoader {
211214 if ( ! webhook )
212215 throw new Error ( `Webhook ${ name } ${ webhookName } is not defined` ) ;
213216
214- let dataKey = webhook . dataKey || apis [ environment ] . dataKey
215- if ( ! dataKey )
217+ // eventDataKey is used to access the event data
218+ let eventDataKey = webhook . eventDataKey || apis [ environment ] . eventDataKey
219+ if ( ! eventDataKey )
216220 throw new Error ( `Webhook ${ name } eventKey is not defined` ) ;
217221
218- let nameKey = webhook . nameKey || apis [ environment ] . nameKey
219- if ( ! nameKey )
220- throw new Error ( `Webhook ${ name } eventKey is not defined` ) ;
222+ // eventNameKey is used to access the event the event name
223+ let eventNameKey = webhook . eventNameKey || apis [ environment ] . eventNameKey
224+ if ( ! eventNameKey )
225+ throw new Error ( `Webhook ${ name } eventNameKey is not defined` ) ;
221226
222227 if ( ! webhook . events )
223228 throw new Error ( `Webhook ${ name } events are not defined` ) ;
224229
225- let rawBody = '' ;
230+ data . rawBody = '' ;
226231 await new Promise ( ( resolve , reject ) => {
227232 data . req . on ( 'data' , chunk => {
228- rawBody += chunk . toString ( ) ;
233+ data . rawBody += chunk . toString ( ) ;
229234 } ) ;
230235 data . req . on ( 'end' , ( ) => {
231236 resolve ( ) ;
@@ -237,18 +242,20 @@ class CoCreateLazyLoader {
237242
238243 let parameters , method
239244
240- if ( webhook . authenticate ) {
245+
246+ if ( webhook . authenticate && webhook . authenticate . method ) {
241247 method = webhook . authenticate . method
242- parameters = webhook . authenticate . parameters
243- }
248+ } else if ( apis [ environment ] . authenticate && apis [ environment ] . authenticate . method ) {
249+ method = apis [ environment ] . authenticate . method
250+ } else
251+ throw new Error ( `Webhook ${ name } authenticate method is not defined` ) ;
244252
245- if ( ! parameters && apis [ environment ] . authenticate && apis [ environment ] . authenticate . parameters ) {
253+ if ( webhook . authenticate && webhook . authenticate . parameters ) {
254+ parameters = webhook . authenticate . parameters
255+ } else if ( apis [ environment ] . authenticate && apis [ environment ] . authenticate . parameters ) {
246256 parameters = apis [ environment ] . authenticate . parameters
247257 } else
248- throw new Error ( `Webhook secret ${ name } is not defined` ) ;
249-
250- if ( ! method && apis [ environment ] . authenticate )
251- method = apis [ environment ] . authenticate . method
258+ throw new Error ( `Webhook ${ name } authenticate parameters is not defined` ) ;
252259
253260 // TODO: webhook secert could be a key pair
254261
@@ -257,7 +264,7 @@ class CoCreateLazyLoader {
257264 if ( ! parameters [ 0 ] !== parameters [ 1 ] )
258265 throw new Error ( `Webhook secret failed for ${ name } . Unauthorized access attempt.` ) ;
259266
260- event = JSON . parse ( rawBody )
267+ event = JSON . parse ( data . rawBody )
261268 } else {
262269 const service = require ( config . path ) ;
263270 let instance
@@ -266,16 +273,20 @@ class CoCreateLazyLoader {
266273 else
267274 instance = new service ( key ) ;
268275
269- event = await executeMethod ( name + '.' + method , methodPath , instance , parameters )
276+ const methodPath = method . split ( '.' )
277+
278+ await processOperators ( data , '' , parameters ) ;
279+
280+ event = await executeMethod ( method , methodPath , instance , parameters )
270281 }
271282
272- let eventName = getValueFromObject ( event , nameKey )
283+ let eventName = getValueFromObject ( event , eventNameKey )
273284 if ( ! eventName )
274- throw new Error ( `Webhook ${ name } nameKey : ${ nameKey } could not be found in the event.` ) ;
285+ throw new Error ( `Webhook ${ name } eventNameKey : ${ eventNameKey } could not be found in the event.` ) ;
275286
276- let eventData = getValueFromObject ( event , dataKey )
287+ let eventData = getValueFromObject ( event , eventDataKey )
277288 if ( ! eventData )
278- throw new Error ( `Webhook ${ name } dataKey : ${ dataKey } could not be found in the event.` ) ;
289+ throw new Error ( `Webhook ${ name } eventDataKey : ${ eventDataKey } could not be found in the event.` ) ;
279290
280291 let execute = webhook . events [ eventName ] ;
281292 if ( execute ) {
@@ -308,40 +319,66 @@ class CoCreateLazyLoader {
308319
309320async function processOperators ( data , event , execute , parent = null , parentKey = null ) {
310321 if ( Array . isArray ( execute ) ) {
311- execute . forEach ( async ( item , index ) => await processOperators ( data , event , item , execute , index ) ) ;
322+ for ( let index = 0 ; index < execute . length ; index ++ ) {
323+ execute [ index ] = await processOperators ( data , event , execute [ index ] , execute , index ) ;
324+ }
312325 } else if ( typeof execute === 'object' && execute !== null ) {
313326 for ( let key of Object . keys ( execute ) ) {
314- // Check if key is an operator
315327 if ( key . startsWith ( '$' ) ) {
316328 const operatorResult = await processOperator ( data , event , key , execute [ key ] ) ;
317- if ( parent && operatorResult !== null ) {
318- if ( parentKey !== null ) {
319- parent [ parentKey ] = operatorResult ;
320- await processOperators ( data , event , parent [ parentKey ] , parent , parentKey ) ;
321- }
322- // else {
323- // // Scenario 2: Replace the key (more complex, might require re-structuring the executable object)
324- // delete parent[key]; // Remove the original key
325- // parent[operatorResult] = execute[key]; // Assign the value to the new key
326- // // Continue processing the new key if necessary
327- // }
329+ if ( parent && operatorResult !== null && parentKey !== null ) {
330+ parent [ parentKey ] = operatorResult ;
331+ await processOperators ( data , event , parent [ parentKey ] , parent , parentKey ) ;
328332 }
329333 } else {
330- await processOperators ( data , event , execute [ key ] , execute , key ) ;
334+ execute [ key ] = await processOperators ( data , event , execute [ key ] , execute , key ) ;
331335 }
332336 }
333337 } else {
334338 return await processOperator ( data , event , execute ) ;
335339 }
340+ return execute ;
336341}
337342
343+ // async function processOperators(data, event, execute, parent = null, parentKey = null) {
344+ // if (Array.isArray(execute)) {
345+ // execute.forEach(async (item, index) => await processOperators(data, event, item, execute, index));
346+ // } else if (typeof execute === 'object' && execute !== null) {
347+ // for (let key of Object.keys(execute)) {
348+ // // Check if key is an operator
349+ // if (key.startsWith('$')) {
350+ // const operatorResult = await processOperator(data, event, key, execute[key]);
351+ // if (parent && operatorResult !== null) {
352+ // if (parentKey !== null) {
353+ // parent[parentKey] = operatorResult;
354+ // await processOperators(data, event, parent[parentKey], parent, parentKey);
355+ // }
356+ // // else {
357+ // // // Scenario 2: Replace the key (more complex, might require re-structuring the executable object)
358+ // // delete parent[key]; // Remove the original key
359+ // // parent[operatorResult] = execute[key]; // Assign the value to the new key
360+ // // // Continue processing the new key if necessary
361+ // // }
362+ // }
363+ // } else {
364+ // await processOperators(data, event, execute[key], execute, key);
365+ // }
366+ // }
367+ // } else {
368+ // return await processOperator(data, event, execute);
369+ // }
370+ // }
371+
338372async function processOperator ( data , event , operator , context ) {
339373 if ( operator . startsWith ( '$data.' ) ) {
340374 operator = getValueFromObject ( data , operator . substring ( 6 ) )
341- } else if ( operator . startsWith ( '$req.' ) ) {
342- operator = getValueFromObject ( data . req , operator . substring ( 5 ) )
343- } else if ( operator . startsWith ( '$header.' ) ) {
344- operator = getValueFromObject ( data . req . header , operator . substring ( 7 ) )
375+ } else if ( operator . startsWith ( '$req' ) ) {
376+ console . log ( operator . substring ( 1 ) )
377+ operator = getValueFromObject ( data , operator . substring ( 1 ) )
378+ } else if ( operator . startsWith ( '$header' ) ) {
379+ operator = getValueFromObject ( data . req , operator . substring ( 1 ) )
380+ } else if ( operator . startsWith ( '$rawBody' ) ) {
381+ operator = getValueFromObject ( data , operator . substring ( 1 ) )
345382 } else if ( operator . startsWith ( '$crud' ) ) {
346383 operator = await data . crud . send ( context )
347384 let name = operator . method . split ( '.' ) [ 0 ]
0 commit comments