@cocreate/lazy-loader 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/docs/index.html +0 -4
- package/package.json +1 -1
- package/src/server.js +184 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
# [1.18.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.17.0...v1.18.0) (2024-03-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* handlng wbhook returned as string or object ([daf7438](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/daf7438bf8d6f049629112d056d9a598499cc23e))
|
|
7
|
+
* imporved authentication handling ([dfc9b1c](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/dfc9b1c8b9fe547ff16d441e4b31b3f0332bacb8))
|
|
8
|
+
* typo executeect updated to object ([a1b6258](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/a1b6258a7a88cd4e9847257fb552852342d9c7e3))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* authentication can be defined at envirnonemt level ([e4bf74c](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/e4bf74cdd8146bd390aec734d29e4177c3b264a7))
|
|
14
|
+
* executeMethod() to handle dotNotion method without losing context ([8ab4f84](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/8ab4f8484073891dba4c154938ae597c21962c5f))
|
|
15
|
+
* processOperators() to execute/rturn operator value ([e948ca2](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/e948ca24c1fb1ba5ae9718aaa466f0e26af78c74))
|
|
16
|
+
|
|
17
|
+
# [1.17.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.16.0...v1.17.0) (2024-02-05)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* $param handeling ([4f1cafc](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/4f1cafc6c598aad0b3e09c794d2a08874560538f))
|
|
23
|
+
* Removed https://cdn.cocreate.app/latest/CoCreate.min.css ([538dd6a](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/538dd6a41df1d32fa71b46c3b2d0da7158c46d74))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
* operate $param[] ([61181ad](https://github.com/CoCreate-app/CoCreate-lazy-loader/commit/61181ad37545b186336bb1a361aff1602ae6868f))
|
|
29
|
+
|
|
1
30
|
# [1.16.0](https://github.com/CoCreate-app/CoCreate-lazy-loader/compare/v1.15.2...v1.16.0) (2024-01-30)
|
|
2
31
|
|
|
3
32
|
|
package/docs/index.html
CHANGED
|
@@ -19,10 +19,6 @@
|
|
|
19
19
|
<meta name="robots" content="index,follow" />
|
|
20
20
|
|
|
21
21
|
<!-- CoCreate CSS CDN -->
|
|
22
|
-
<link
|
|
23
|
-
rel="stylesheet"
|
|
24
|
-
href="https://cdn.cocreate.app/latest/CoCreate.min.css"
|
|
25
|
-
type="text/css" />
|
|
26
22
|
|
|
27
23
|
<link rel="manifest" href="/manifest.webmanifest" />
|
|
28
24
|
</head>
|
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -47,6 +47,7 @@ class CoCreateLazyLoader {
|
|
|
47
47
|
const valideUrl = new URL(`http://${req.headers.host}${req.url}`);
|
|
48
48
|
const hostname = valideUrl.hostname;
|
|
49
49
|
let organization
|
|
50
|
+
|
|
50
51
|
try {
|
|
51
52
|
organization = await this.crud.getOrganization({ host: hostname });
|
|
52
53
|
} catch {
|
|
@@ -75,7 +76,7 @@ class CoCreateLazyLoader {
|
|
|
75
76
|
|
|
76
77
|
async executeScriptWithTimeout(name, data) {
|
|
77
78
|
try {
|
|
78
|
-
if (this.modules[name].initialize) {
|
|
79
|
+
if (this.modules[name].initialize || this.modules[name].initialize === '') {
|
|
79
80
|
if (data.req)
|
|
80
81
|
data = await this.webhooks(this.modules[name], data, name)
|
|
81
82
|
else
|
|
@@ -158,21 +159,33 @@ class CoCreateLazyLoader {
|
|
|
158
159
|
throw new Error(`Missing ${name} key in organization apis object`);
|
|
159
160
|
|
|
160
161
|
const service = require(config.path);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
let instance
|
|
163
|
+
if (config.initialize)
|
|
164
|
+
instance = new service[config.initialize](key);
|
|
165
|
+
else
|
|
166
|
+
instance = new service(key);
|
|
167
|
+
|
|
168
|
+
let params = [], mainParam = false
|
|
169
|
+
for (let i = 0; true; i++) {
|
|
170
|
+
if (`$param[${i}]` in data[name]) {
|
|
171
|
+
params.push(data[name][`$param[${i}]`])
|
|
172
|
+
delete data[name][`$param[${i}]`]
|
|
173
|
+
} else if (!mainParam) {
|
|
174
|
+
params.push(data[name])
|
|
175
|
+
mainParam = true
|
|
176
|
+
} else {
|
|
177
|
+
break;
|
|
168
178
|
}
|
|
169
179
|
}
|
|
170
180
|
|
|
171
|
-
|
|
172
|
-
|
|
181
|
+
// TODO: should run processOperators before in order to perform complex opertions and get data
|
|
182
|
+
// data[name] = await processOperators(data, null, data[name]);
|
|
183
|
+
|
|
184
|
+
data[name] = await executeMethod(data.method, methodPath, instance, params)
|
|
185
|
+
|
|
186
|
+
// TODO: should run processOperators after in order to perform complex opertions and get data
|
|
187
|
+
// data[name] = await processOperators(data, data[name]);
|
|
173
188
|
|
|
174
|
-
let params = data.$params || [data[name]]
|
|
175
|
-
data.postmark = await method.apply(instance, params);
|
|
176
189
|
return data
|
|
177
190
|
} catch (error) {
|
|
178
191
|
data.error = error.message
|
|
@@ -191,13 +204,23 @@ class CoCreateLazyLoader {
|
|
|
191
204
|
if (!key)
|
|
192
205
|
throw new Error(`Missing ${name} key in organization apis object`);
|
|
193
206
|
|
|
194
|
-
let
|
|
195
|
-
|
|
207
|
+
let webhookName = data.req.url.split('/');
|
|
208
|
+
webhookName = webhookName[webhookName.length - 1]
|
|
196
209
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
210
|
+
const webhook = apis[environment].webhooks[webhookName];
|
|
211
|
+
if (!webhook)
|
|
212
|
+
throw new Error(`Webhook ${name} ${webhookName} is not defined`);
|
|
213
|
+
|
|
214
|
+
let dataKey = webhook.dataKey || apis[environment].dataKey
|
|
215
|
+
if (!dataKey)
|
|
216
|
+
throw new Error(`Webhook ${name} eventKey is not defined`);
|
|
217
|
+
|
|
218
|
+
let nameKey = webhook.nameKey || apis[environment].nameKey
|
|
219
|
+
if (!nameKey)
|
|
220
|
+
throw new Error(`Webhook ${name} eventKey is not defined`);
|
|
221
|
+
|
|
222
|
+
if (!webhook.events)
|
|
223
|
+
throw new Error(`Webhook ${name} events are not defined`);
|
|
201
224
|
|
|
202
225
|
let rawBody = '';
|
|
203
226
|
await new Promise((resolve, reject) => {
|
|
@@ -212,13 +235,52 @@ class CoCreateLazyLoader {
|
|
|
212
235
|
});
|
|
213
236
|
});
|
|
214
237
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
let parameters, method
|
|
239
|
+
|
|
240
|
+
if (webhook.authenticate) {
|
|
241
|
+
method = webhook.authenticate.method
|
|
242
|
+
parameters = webhook.authenticate.parameters
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!parameters && apis[environment].authenticate && apis[environment].authenticate.parameters) {
|
|
246
|
+
parameters = apis[environment].authenticate.parameters
|
|
247
|
+
} else
|
|
248
|
+
throw new Error(`Webhook secret ${name} is not defined`);
|
|
218
249
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
250
|
+
if (!method && apis[environment].authenticate)
|
|
251
|
+
method = apis[environment].authenticate.method
|
|
252
|
+
|
|
253
|
+
// TODO: webhook secert could be a key pair
|
|
254
|
+
|
|
255
|
+
let event
|
|
256
|
+
if (!method) {
|
|
257
|
+
if (!parameters[0] !== parameters[1])
|
|
258
|
+
throw new Error(`Webhook secret failed for ${name}. Unauthorized access attempt.`);
|
|
259
|
+
|
|
260
|
+
event = JSON.parse(rawBody)
|
|
261
|
+
} else {
|
|
262
|
+
const service = require(config.path);
|
|
263
|
+
let instance
|
|
264
|
+
if (config.initialize)
|
|
265
|
+
instance = new service[config.initialize](key);
|
|
266
|
+
else
|
|
267
|
+
instance = new service(key);
|
|
268
|
+
|
|
269
|
+
event = await executeMethod(name + '.' + method, methodPath, instance, parameters)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let eventName = getValueFromObject(event, nameKey)
|
|
273
|
+
if (!eventName)
|
|
274
|
+
throw new Error(`Webhook ${name} nameKey: ${nameKey} could not be found in the event.`);
|
|
275
|
+
|
|
276
|
+
let eventData = getValueFromObject(event, dataKey)
|
|
277
|
+
if (!eventData)
|
|
278
|
+
throw new Error(`Webhook ${name} dataKey: ${dataKey} could not be found in the event.`);
|
|
279
|
+
|
|
280
|
+
let execute = webhook.events[eventName];
|
|
281
|
+
if (execute) {
|
|
282
|
+
execute = await processOperators(data, event, execute);
|
|
283
|
+
}
|
|
222
284
|
|
|
223
285
|
data.res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
224
286
|
data.res.end(JSON.stringify({ message: 'Webhook received and processed' }));
|
|
@@ -244,6 +306,101 @@ class CoCreateLazyLoader {
|
|
|
244
306
|
|
|
245
307
|
}
|
|
246
308
|
|
|
309
|
+
async function processOperators(data, event, execute, parent = null, parentKey = null) {
|
|
310
|
+
if (Array.isArray(execute)) {
|
|
311
|
+
execute.forEach(async (item, index) => await processOperators(data, event, item, execute, index));
|
|
312
|
+
} else if (typeof execute === 'object' && execute !== null) {
|
|
313
|
+
for (let key of Object.keys(execute)) {
|
|
314
|
+
// Check if key is an operator
|
|
315
|
+
if (key.startsWith('$')) {
|
|
316
|
+
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
|
+
// }
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
await processOperators(data, event, execute[key], execute, key);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
return await processOperator(data, event, execute);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async function processOperator(data, event, operator, context) {
|
|
339
|
+
if (operator.startsWith('$data.')) {
|
|
340
|
+
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))
|
|
345
|
+
} else if (operator.startsWith('$crud')) {
|
|
346
|
+
operator = await data.crud.send(context)
|
|
347
|
+
let name = operator.method.split('.')[0]
|
|
348
|
+
operator = operator[name]
|
|
349
|
+
} else if (operator.startsWith('$socket')) {
|
|
350
|
+
operator = await data.socket.send(context)
|
|
351
|
+
let name = operator.method.split('.')[0]
|
|
352
|
+
operator = operator[name]
|
|
353
|
+
} else if (operator.startsWith('$api')) {
|
|
354
|
+
let name = context.method.split('.')[0]
|
|
355
|
+
operator = this.executeScriptWithTimeout(name, context)
|
|
356
|
+
} else if (operator.startsWith('$webhook.')) {
|
|
357
|
+
operator = getValueFromObject(webhook, operator.substring(9))
|
|
358
|
+
} else if (operator.startsWith('$event.')) {
|
|
359
|
+
operator = getValueFromObject(event, operator.substring(7))
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return operator;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async function executeMethod(method, methodPath, instance, params) {
|
|
366
|
+
try {
|
|
367
|
+
switch (methodPath.length) {
|
|
368
|
+
case 1:
|
|
369
|
+
return await instance[methodPath[0]](...params)
|
|
370
|
+
case 2:
|
|
371
|
+
return await instance[methodPath[0]][methodPath[1]](...params);
|
|
372
|
+
case 3:
|
|
373
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]](...params);
|
|
374
|
+
case 4:
|
|
375
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]][methodPath[3]](...params);
|
|
376
|
+
case 5:
|
|
377
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]][methodPath[3]][methodPath[4]](...params);
|
|
378
|
+
case 6:
|
|
379
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]][methodPath[3]][methodPath[4]][methodPath[5]](...params);
|
|
380
|
+
case 7:
|
|
381
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]][methodPath[3]][methodPath[4]][methodPath[5]][methodPath[6]](...params);
|
|
382
|
+
case 8:
|
|
383
|
+
return await instance[methodPath[0]][methodPath[1]][methodPath[2]][methodPath[3]][methodPath[4]][methodPath[5]][methodPath[6]][methodPath[7]](...params);
|
|
384
|
+
default:
|
|
385
|
+
const methodName = methodPath.pop();
|
|
386
|
+
let Method = instance
|
|
387
|
+
for (let i = 0; i < methodPath.length; i++) {
|
|
388
|
+
Method = Method[methodPath[i]]
|
|
389
|
+
if (Method === undefined) {
|
|
390
|
+
throw new Error(`Method ${methodPath[i]} not found using ${method}.`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (typeof Method[methodName] !== 'function')
|
|
395
|
+
throw new Error(`Method ${method} is not a function.`);
|
|
396
|
+
|
|
397
|
+
return await Method[methodName](...params)
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
throw new Error(`Method ${method} not found.`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
247
404
|
function getModuleDependencies(modulePath) {
|
|
248
405
|
let moduleObj = require.cache[modulePath];
|
|
249
406
|
if (!moduleObj) {
|
|
@@ -330,4 +487,7 @@ async function fetchScriptFromDatabaseAndSave(name, moduleConfig) {
|
|
|
330
487
|
return src;
|
|
331
488
|
}
|
|
332
489
|
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
|
|
333
493
|
module.exports = CoCreateLazyLoader;
|