@ductape/sdk 0.0.3-beta8 → 0.0.4-v2

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.
Files changed (115) hide show
  1. package/dist/api/services/appApi.service.d.ts +3 -1
  2. package/dist/api/services/appApi.service.js +41 -2
  3. package/dist/api/services/appApi.service.js.map +1 -1
  4. package/dist/api/services/processorApi.service.d.ts +5 -1
  5. package/dist/api/services/processorApi.service.js +18 -0
  6. package/dist/api/services/processorApi.service.js.map +1 -1
  7. package/dist/api/services/productsApi.service.d.ts +2 -1
  8. package/dist/api/services/productsApi.service.js +2 -2
  9. package/dist/api/services/productsApi.service.js.map +1 -1
  10. package/dist/api/services/userApi.service.d.ts +2 -1
  11. package/dist/api/services/userApi.service.js +1 -1
  12. package/dist/api/services/userApi.service.js.map +1 -1
  13. package/dist/api/services/webhooksApi.service.d.ts +4 -1
  14. package/dist/api/services/webhooksApi.service.js +6 -3
  15. package/dist/api/services/webhooksApi.service.js.map +1 -1
  16. package/dist/api/services/workspaceApi.service.d.ts +2 -1
  17. package/dist/api/services/workspaceApi.service.js +1 -1
  18. package/dist/api/services/workspaceApi.service.js.map +1 -1
  19. package/dist/api/urls.d.ts +2 -0
  20. package/dist/api/urls.js +3 -1
  21. package/dist/api/urls.js.map +1 -1
  22. package/dist/api/utils/cache.utils.d.ts +3 -0
  23. package/dist/api/utils/cache.utils.js +18 -0
  24. package/dist/api/utils/cache.utils.js.map +1 -0
  25. package/dist/apps/services/app.service.d.ts +3 -3
  26. package/dist/apps/services/app.service.js +153 -75
  27. package/dist/apps/services/app.service.js.map +1 -1
  28. package/dist/apps/utils/objects.utils.d.ts +1 -1
  29. package/dist/apps/utils/objects.utils.js +5 -3
  30. package/dist/apps/utils/objects.utils.js.map +1 -1
  31. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +1 -1
  32. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
  33. package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js +1 -0
  34. package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js.map +1 -1
  35. package/dist/apps/validators/joi-validators/update.appAction.validator.d.ts +2 -2
  36. package/dist/apps/validators/joi-validators/update.appAction.validator.js +11 -11
  37. package/dist/apps/validators/joi-validators/update.appAction.validator.js.map +1 -1
  38. package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js +2 -0
  39. package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js.map +1 -1
  40. package/dist/clients/webhooks.client.d.ts +2 -1
  41. package/dist/clients/webhooks.client.js +2 -2
  42. package/dist/clients/webhooks.client.js.map +1 -1
  43. package/dist/imports/imports.service.d.ts +2 -3
  44. package/dist/imports/imports.service.js +4 -45
  45. package/dist/imports/imports.service.js.map +1 -1
  46. package/dist/imports/imports.types.d.ts +238 -0
  47. package/dist/imports/repos/openApi.repo.d.ts +5 -11
  48. package/dist/imports/repos/openApi.repo.js +77 -27
  49. package/dist/imports/repos/openApi.repo.js.map +1 -1
  50. package/dist/imports/repos/postmanV21.repo.js +1 -1
  51. package/dist/imports/repos/postmanV21.repo.js.map +1 -1
  52. package/dist/index.d.ts +24 -6
  53. package/dist/index.js +59 -4
  54. package/dist/index.js.map +1 -1
  55. package/dist/inputs/validators/inputs.validator.parse.js +1 -0
  56. package/dist/inputs/validators/inputs.validator.parse.js.map +1 -1
  57. package/dist/logs/logs.service.d.ts +1 -1
  58. package/dist/logs/logs.types.d.ts +3 -0
  59. package/dist/logs/logs.types.js.map +1 -1
  60. package/dist/processor/services/fallback.service.d.ts +0 -1
  61. package/dist/processor/services/fallback.service.js +0 -16
  62. package/dist/processor/services/fallback.service.js.map +1 -1
  63. package/dist/processor/services/processor.service.d.ts +53 -14
  64. package/dist/processor/services/processor.service.js +429 -152
  65. package/dist/processor/services/processor.service.js.map +1 -1
  66. package/dist/processor/services/quota.service.d.ts +6 -13
  67. package/dist/processor/services/quota.service.js +12 -3
  68. package/dist/processor/services/quota.service.js.map +1 -1
  69. package/dist/processor/utils/processor.utils.d.ts +3 -230
  70. package/dist/processor/utils/processor.utils.js +133 -118
  71. package/dist/processor/utils/processor.utils.js.map +1 -1
  72. package/dist/products/services/products.service.d.ts +22 -6
  73. package/dist/products/services/products.service.js +348 -146
  74. package/dist/products/services/products.service.js.map +1 -1
  75. package/dist/products/utils/functions.utils.d.ts +1 -0
  76. package/dist/products/utils/functions.utils.js +11 -0
  77. package/dist/products/utils/functions.utils.js.map +1 -1
  78. package/dist/products/validators/index.d.ts +3 -1
  79. package/dist/products/validators/index.js +5 -1
  80. package/dist/products/validators/index.js.map +1 -1
  81. package/dist/products/validators/joi-validators/create.productFallback.validator.js +7 -1
  82. package/dist/products/validators/joi-validators/create.productFallback.validator.js.map +1 -1
  83. package/dist/products/validators/joi-validators/create.productFeature.validator.js +2 -0
  84. package/dist/products/validators/joi-validators/create.productFeature.validator.js.map +1 -1
  85. package/dist/products/validators/joi-validators/create.productQuota.validator.js +10 -2
  86. package/dist/products/validators/joi-validators/create.productQuota.validator.js.map +1 -1
  87. package/dist/products/validators/joi-validators/create.userAuth.validator.d.ts +3 -0
  88. package/dist/products/validators/joi-validators/create.userAuth.validator.js +47 -0
  89. package/dist/products/validators/joi-validators/create.userAuth.validator.js.map +1 -0
  90. package/dist/products/validators/joi-validators/update.dataValue.validator.d.ts +1 -1
  91. package/dist/products/validators/joi-validators/update.dataValue.validator.js +3 -2
  92. package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
  93. package/dist/products/validators/joi-validators/update.productFallback.validator.js +7 -2
  94. package/dist/products/validators/joi-validators/update.productFallback.validator.js.map +1 -1
  95. package/dist/products/validators/joi-validators/update.productFeature.validator.js +2 -0
  96. package/dist/products/validators/joi-validators/update.productFeature.validator.js.map +1 -1
  97. package/dist/products/validators/joi-validators/update.productQuota.validator.js +12 -7
  98. package/dist/products/validators/joi-validators/update.productQuota.validator.js.map +1 -1
  99. package/dist/products/validators/joi-validators/update.userAuth.validator.d.ts +3 -0
  100. package/dist/products/validators/joi-validators/update.userAuth.validator.js +47 -0
  101. package/dist/products/validators/joi-validators/update.userAuth.validator.js.map +1 -0
  102. package/dist/test/test.import.openapi.d.ts +1 -0
  103. package/dist/test/test.import.openapi.js +76 -0
  104. package/dist/test/test.import.openapi.js.map +1 -0
  105. package/dist/test/test.logs.js +1 -2
  106. package/dist/test/test.logs.js.map +1 -1
  107. package/dist/types/appBuilder.types.d.ts +19 -1
  108. package/dist/types/enums.d.ts +6 -0
  109. package/dist/types/enums.js +8 -1
  110. package/dist/types/enums.js.map +1 -1
  111. package/dist/types/processor.types.d.ts +26 -0
  112. package/dist/types/processor.types.js.map +1 -1
  113. package/dist/types/productsBuilder.types.d.ts +20 -7
  114. package/dist/types/productsBuilder.types.js.map +1 -1
  115. package/package.json +6 -2
@@ -40,16 +40,18 @@ const update_productNotificationMessage_validator_1 = __importDefault(require(".
40
40
  const create_productNotification_validator_1 = require("../validators/joi-validators/create.productNotification.validator");
41
41
  const functions_utils_1 = require("../utils/functions.utils");
42
42
  const objects_utils_2 = require("../../apps/utils/objects.utils");
43
+ const webhooksApi_service_1 = require("../../api/services/webhooksApi.service");
43
44
  class ProductsBuilderService {
44
- constructor({ workspace_id, public_key, user_id, token, env_type }) {
45
+ constructor({ workspace_id, public_key, user_id, token, env_type, redis_client }) {
45
46
  this.workspace_id = workspace_id;
46
47
  this.public_key = public_key;
47
48
  this.user_id = user_id;
48
49
  this.token = token;
49
- this.userApi = new userApi_service_1.UserApiService(env_type);
50
- this.productApi = new productsApi_service_1.ProductsApiService(env_type);
51
- this.workspaceApi = new workspaceApi_service_1.WorkspaceApiService(env_type);
52
- this.appApi = new appApi_service_1.AppApiService(env_type);
50
+ this.userApi = new userApi_service_1.UserApiService(env_type, redis_client);
51
+ this.productApi = new productsApi_service_1.ProductsApiService(env_type, redis_client);
52
+ this.workspaceApi = new workspaceApi_service_1.WorkspaceApiService(env_type, redis_client);
53
+ this.webhooksApi = new webhooksApi_service_1.WebhooksApiService(env_type);
54
+ this.appApi = new appApi_service_1.AppApiService(env_type, redis_client);
53
55
  this.inputsService = new inputs_service_1.default();
54
56
  this.thirdPartyApps = [];
55
57
  }
@@ -190,6 +192,59 @@ class ProductsBuilderService {
190
192
  }
191
193
  return this.product;
192
194
  }
195
+ async createSession(data) {
196
+ try {
197
+ // TODO: figure out a way to check if this has run before, halt if it has
198
+ if (!this.fetchSession(data.tag)) {
199
+ await validators_1.CreateProductSessionSchema.validateAsync(data);
200
+ data.schema_data = (await this.inputsService.parseJson({
201
+ data: data.schema,
202
+ expected: inputs_types_1.ExpectedValues.PARSESAMPLE,
203
+ category: enums_1.Categories.DATA,
204
+ }));
205
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.SESSION, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
206
+ await this.initializeProduct(this.product_id);
207
+ }
208
+ }
209
+ catch (e) {
210
+ throw e;
211
+ }
212
+ }
213
+ async updateSession(tag, data) {
214
+ try {
215
+ const auth = this.fetchSession(tag);
216
+ if (!auth) {
217
+ throw new Error(`Session ${tag} not found`);
218
+ }
219
+ //const { _id } = auth;
220
+ await validators_1.UpdateProductSessionSchema.validateAsync(data); // Change to update;
221
+ if (data.tag && this.fetchEnv(data.tag) && data.tag !== tag) {
222
+ throw new Error(`tag ${data.tag} is in use`); // TODO: also check on the backend
223
+ }
224
+ if (!data.tag) {
225
+ data.tag = tag;
226
+ }
227
+ if (data.schema) {
228
+ data.schema_data = (await this.inputsService.parseJson({
229
+ data: data.schema,
230
+ expected: inputs_types_1.ExpectedValues.PARSESAMPLE,
231
+ category: enums_1.Categories.DATA,
232
+ }));
233
+ }
234
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, Object.assign(Object.assign({}, auth), data)), { component: enums_1.ProductComponents.SESSION, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
235
+ await this.initializeProduct(this.product_id);
236
+ }
237
+ catch (e) {
238
+ throw e;
239
+ }
240
+ }
241
+ fetchSession(tag) {
242
+ var _a;
243
+ return (_a = this.product.sessions) === null || _a === void 0 ? void 0 : _a.find((auth) => auth.tag === tag);
244
+ }
245
+ fetchSessions() {
246
+ return this.product.sessions;
247
+ }
193
248
  async createMessageBrokerTopic(data, throwErrorIfExists = false) {
194
249
  try {
195
250
  if (!data.tag) {
@@ -277,15 +332,15 @@ class ProductsBuilderService {
277
332
  throw new Error(`Message Broker ${messageBrokerTag} not found`);
278
333
  return messageBroker.topics;
279
334
  }
280
- async validateQuotaFallbackInputAndOutput(data) {
335
+ async validateQuotaFallbackInputAndOutput(data, type) {
281
336
  const input = data.input;
282
337
  await Promise.all(data.options.map(async (d, index) => {
283
- await this.validateQuotaFallbackInput(d, input);
338
+ await this.validateQuotaFallbackInput(d, input, type);
284
339
  const pastOutput = index > 0 ? data.options[index - 1].output : null;
285
- await this.validateQuotaFallbackOutput(d, pastOutput, input);
340
+ await this.validateQuotaFallbackOutput(d, pastOutput, input, type);
286
341
  }));
287
342
  }
288
- async validateQuotaFallbackInput(option, input) {
343
+ async validateQuotaFallbackInput(option, input, type) {
289
344
  if (option.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
290
345
  const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
291
346
  if (!appData) {
@@ -297,55 +352,170 @@ class ProductsBuilderService {
297
352
  if (!appData) {
298
353
  throw new Error(`Action ${option.event} not found in ${option.app} version ${version}`);
299
354
  }
300
- await this.validateActionDataInput({ input }, action, option.input, 0, 0);
355
+ //await this.validateActionDataInput({ input }, action, option.input, 0, 0);
356
+ // const keyValues = traverseObject(input.option);
357
+ //query
358
+ this.checkActionQuotaFallbackInput(action.query, option.input.query, input, 'query');
359
+ //headers
360
+ this.checkActionQuotaFallbackInput(action.headers, option.input.headers, input, 'headers');
361
+ // params
362
+ this.checkActionQuotaFallbackInput(action.params, option.input.params, input, 'params');
363
+ //body
364
+ this.checkActionQuotaFallbackInput(action.body, option.input.body, input, 'body');
301
365
  }
302
366
  else {
303
367
  const feature = this.fetchFeature(option.event);
304
368
  if (!feature) {
305
369
  throw new Error(`Feature ${option.event} not found`);
306
370
  }
307
- (0, objects_utils_2.validateObjectKeys)(feature.input, option.input);
308
- const keyValues = (0, objects_utils_1.traverseObject)(option.input);
371
+ const map = (0, functions_utils_1.convertInputToValueMap)(feature.input);
372
+ (0, objects_utils_2.validateObjectKeys)(map, option.input, '', 'option input', 'feature input definition');
373
+ }
374
+ const keyValues = (0, objects_utils_1.traverseObject)(option.input);
375
+ this.checkKeyValuesInput(keyValues, input, type);
376
+ this.isQuotaFallbackInput = false;
377
+ }
378
+ checkKeyValuesInput(keyValues, input, type) {
379
+ for (let keyValue of keyValues) {
380
+ const { key, value } = keyValue;
381
+ if (!String(value).startsWith('$')) {
382
+ }
383
+ else if (String(value).startsWith('$Auth{')) {
384
+ // TODO: validate auth input later
385
+ }
386
+ else if (String(value).startsWith('$') && !String(value).startsWith('$Input{')) {
387
+ this.checkFuncArgsForInputs(String(value).trim(), input, type);
388
+ }
389
+ else if (!String(value).startsWith('$Input{')) {
390
+ throw new Error(`Feature input ${value} is invalid, all feature Inputs are expected to start with $Input{}`);
391
+ }
392
+ else {
393
+ this.checkInput(String(value).trim(), input, type);
394
+ }
395
+ }
396
+ }
397
+ checkActionQuotaFallbackInput(sample, obj, featureInput, type) {
398
+ const data = (0, objects_utils_1.traverseObject)(obj);
399
+ //compare obj keys to sample keys
400
+ (0, objects_utils_2.validateObjectKeys)(sample.sample ? JSON.parse(String(sample.sample)) : {}, obj, '', `action ${type} input`, `action ${type} input sample`);
401
+ // check if values in data can be found inside featureInput
402
+ this.checkKeyValuesInput(data, featureInput, type);
403
+ }
404
+ checkFuncArgsForInputs(value, input, type) {
405
+ const isFunc = (0, functions_utils_1.startsWithFunctionAndEndsWithParen)(value);
406
+ if (!isFunc) {
407
+ throw new Error(`Invalid function call ${value}`);
408
+ }
409
+ const funcArgs = (0, functions_utils_1.extractFunctionAndArgs)(value);
410
+ if (funcArgs && funcArgs.args.length) {
411
+ funcArgs.args.map((arg) => {
412
+ const args = arg.trim().split(',');
413
+ args.map((argz) => {
414
+ const arg = argz.trim();
415
+ if (arg.startsWith('$') && !arg.startsWith('$Input{')) {
416
+ this.checkFuncArgsForInputs(arg, input, type);
417
+ }
418
+ else if (arg.startsWith('$Input{')) {
419
+ this.checkInput(arg, input, type);
420
+ }
421
+ });
422
+ });
423
+ }
424
+ }
425
+ checkInput(value, input, type) {
426
+ const stages = this.extractStages(value);
427
+ if (stages.length > 1) {
428
+ throw new Error(`Invalid input ${value}, nested locators not allowed in $Input`);
429
+ }
430
+ if (!input[stages[0]]) {
431
+ throw new Error(`${value} not found in ${type} input definition`);
432
+ }
433
+ }
434
+ async validateQuotaFallbackOutput(option, pastResponse, input, type) {
435
+ if (pastResponse) {
436
+ (0, objects_utils_2.validateObjectKeys)(option.output, pastResponse, `previous outputs`, `${option.event} ${type} output`);
437
+ }
438
+ if (option.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
439
+ const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
440
+ if (!appData) {
441
+ throw new Error(`App ${option.app} not found`);
442
+ }
443
+ const { actions } = appData.versions.find((data) => data.tag === version);
444
+ const action = actions.find((data) => data.tag === option.event);
445
+ if (!appData) {
446
+ throw new Error(`Action ${event} not found in ${option.app} version ${version}`);
447
+ }
448
+ const response = action.responses.find((item) => item.success === true);
449
+ // fetch success result
450
+ if (!response) {
451
+ throw new Error(`event ${event} does not have a success response`);
452
+ }
453
+ // validate that each output item starts with response or Input and then validate the stages are valid;
454
+ }
455
+ else {
456
+ // fetch feature
457
+ const feature = this.fetchFeature(option.event);
458
+ if (!feature) {
459
+ throw new Error(`Feature ${option.event} not found`);
460
+ }
461
+ const { output } = feature;
462
+ const keyValues = (0, objects_utils_1.traverseObject)(option.output);
309
463
  for (let keyValue of keyValues) {
310
464
  const { key, value } = keyValue;
311
- if (!value.startsWith('$Input{')) {
312
- //throw new Error(`Feature input ${value} is invalid, all feature Inputs are expected to start with $Input{}`);
465
+ if (!value.startsWith('$')) {
466
+ }
467
+ else if (value.startsWith('$') && !value.startsWith('$Response{') && !value.startsWith('$Input')) {
468
+ this.checkFuncArgsForResponse(value.trim(), output, input, type);
469
+ }
470
+ else if (!value.startsWith('$Response{') && !value.startsWith('$Input{')) {
471
+ throw new Error(`Feature output ${value} is invalid, all feature outputs for ${type} are expected to start with $Response or $Input{}`);
472
+ }
473
+ else if (value.startsWith('$Response')) {
474
+ this.checkResponse(value.trim(), output, input, type);
475
+ }
476
+ else if (value.startsWith('$Input')) {
477
+ this.checkInput(value, input, type);
313
478
  }
314
479
  }
315
480
  }
316
- this.isQuotaFallbackInput = false;
481
+ // validate that each response matches the expected format
482
+ /**await this.validateActionResponse(response, res)*/
317
483
  }
318
- async validateQuotaFallbackOutput(
319
- /*app: string,
320
- event: string,
321
- response: Record<string, unknown>,
322
- input: Record<string, IFeatureInput>,*/
323
- option, pastResponse, input) {
324
- /*const { version, ...appData } = await this.fetchThirdPartyAppByAccessTag(option.app);
325
-
326
- if (!appData) {
327
- throw new Error(`App ${option.app} not found`);
328
- }
329
-
330
- const { actions } = appData.versions.find((data) => data.tag === version);
331
-
332
- const action = actions.find((data) => data.tag === option.event);
333
-
334
- if (!appData) {
335
- throw new Error(`Action ${event} not found in ${option.app} version ${version}`);
484
+ checkFuncArgsForResponse(value, output, input, type) {
485
+ const isFunc = (0, functions_utils_1.startsWithFunctionAndEndsWithParen)(value);
486
+ if (!isFunc) {
487
+ throw new Error(`Invalid function call ${value}`);
336
488
  }
337
- if (pastResponse) {
338
- validateObjectKeys(response, pastResponse);
489
+ const funcArgs = (0, functions_utils_1.extractFunctionAndArgs)(value);
490
+ if (funcArgs && funcArgs.args.length) {
491
+ funcArgs.args.map((arg) => {
492
+ const args = arg.trim().split(',');
493
+ args.map((argz) => {
494
+ const arg = argz.trim();
495
+ if (arg.startsWith('$') && !arg.startsWith('$Response{') && !arg.startsWith('$Input{')) {
496
+ this.checkFuncArgsForResponse(arg, output, input, type);
497
+ }
498
+ else if (arg.startsWith('$Response{')) {
499
+ this.checkResponse(arg, output, input, type);
500
+ }
501
+ else if (arg.startsWith('$Input{')) {
502
+ this.checkInput(arg, input, type);
503
+ }
504
+ });
505
+ });
339
506
  }
340
-
341
- const res = action.responses.find((item) => item.success === true);
342
- // fetch success result
343
-
344
- if (!res) {
345
- throw new Error(`event ${event} does not have a success response`);
507
+ }
508
+ checkResponse(value, output, input, type) {
509
+ const stages = this.extractStages(value);
510
+ let current = output;
511
+ for (const stage of stages) {
512
+ if (current && typeof current === 'object' && stage in current) {
513
+ current = current[stage];
514
+ }
515
+ else {
516
+ throw new Error(`${value} not found in ${type} response definition`);
517
+ }
346
518
  }
347
-
348
- await this.validateActionResponse(response, res)*/
349
519
  }
350
520
  async createQuota(data) {
351
521
  try {
@@ -354,27 +524,32 @@ class ProductsBuilderService {
354
524
  }
355
525
  if (!this.fetchQuota(data.tag)) {
356
526
  await validators_1.CreateProductQuotaSchema.validateAsync(data);
357
- await this.validateQuotaFallbackInputAndOutput(data);
527
+ await this.validateQuotaFallbackInputAndOutput(data, 'quota');
358
528
  data.total_quota = 0;
359
529
  data.total_init = 0;
360
530
  await Promise.all(data.options.map(async (d) => {
361
531
  data.total_quota += d.quota;
362
- const app = await this.fetchThirdPartyAppByAccessTag(d.app);
363
- if (!app) {
364
- throw new Error(`App with access tag ${d.app} not found`);
365
- }
366
- const version = app.versions.find((version) => version.tag === app.version);
367
- const action = version.actions.find((action) => action.tag === d.event);
368
- if (!action) {
369
- throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
370
- }
371
- if (d.healthcheck) {
372
- const action = version.actions.find((action) => action.tag === d.healthcheck);
373
- if (!d.check_interval) {
374
- d.check_interval = 10000;
532
+ if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
533
+ const app = await this.fetchThirdPartyAppByAccessTag(d.app);
534
+ if (!app) {
535
+ throw new Error(`App with access tag ${d.app} not found`);
375
536
  }
537
+ const version = app.versions.find((version) => version.tag === app.version);
538
+ const action = version.actions.find((action) => action.tag === d.event);
376
539
  if (!action) {
377
- throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
540
+ throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
541
+ }
542
+ if (d.healthcheck) {
543
+ const action = version.actions.find((action) => action.tag === d.healthcheck);
544
+ if (!d.check_interval) {
545
+ d.check_interval = 10000;
546
+ }
547
+ if (!action) {
548
+ throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
549
+ }
550
+ if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
551
+ throw new Error('Healthcheck action is expected to have no headers, body, params or query');
552
+ }
378
553
  }
379
554
  }
380
555
  d.last_checked = new Date();
@@ -383,15 +558,61 @@ class ProductsBuilderService {
383
558
  }));
384
559
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.QUOTA, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
385
560
  }
561
+ }
562
+ catch (e) {
563
+ throw e;
564
+ }
565
+ }
566
+ async updateQuota(tag, data) {
567
+ try {
568
+ const quota = this.fetchQuota(tag);
569
+ if (quota) {
570
+ await validators_1.UpdateProductQuotaSchema.validateAsync(data);
571
+ if (data.options) {
572
+ await this.validateQuotaFallbackInputAndOutput(data, 'quota');
573
+ data.total_quota = 0;
574
+ data.total_init = 0;
575
+ data.tag = tag;
576
+ await Promise.all(data.options.map(async (d) => {
577
+ data.total_quota += d.quota;
578
+ if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
579
+ const app = await this.fetchThirdPartyAppByAccessTag(d.app);
580
+ if (!app) {
581
+ throw new Error(`App with access tag ${d.app} not found`);
582
+ }
583
+ const version = app.versions.find((version) => version.tag === app.version);
584
+ const action = version.actions.find((action) => action.tag === d.event);
585
+ if (!action) {
586
+ throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
587
+ }
588
+ if (d.healthcheck) {
589
+ const action = version.actions.find((action) => action.tag === d.healthcheck);
590
+ if (!d.check_interval) {
591
+ d.check_interval = 10000;
592
+ }
593
+ if (!action) {
594
+ throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
595
+ }
596
+ if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
597
+ throw new Error('Healthcheck action is expected to have no headers, body, params or query');
598
+ }
599
+ }
600
+ }
601
+ d.last_checked = new Date();
602
+ d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
603
+ d.last_available = true;
604
+ }));
605
+ }
606
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, quota), data), { component: enums_1.ProductComponents.QUOTA, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
607
+ }
386
608
  else {
387
- throw new Error(`Quota with tag ${data.tag} already exists`);
609
+ throw new Error(`Quota with tag ${data.tag} not found`);
388
610
  }
389
611
  }
390
612
  catch (e) {
391
613
  throw e;
392
614
  }
393
615
  }
394
- async updateQuota(tag, data) { }
395
616
  fetchQuota(tag) {
396
617
  return this.fetchQuotas().find((data) => data.tag === tag);
397
618
  }
@@ -403,26 +624,31 @@ class ProductsBuilderService {
403
624
  if (!data.tag) {
404
625
  throw new Error('tag field is required');
405
626
  }
406
- if (!this.fetchQuota(data.tag)) {
627
+ if (!this.fetchFallback(data.tag)) {
407
628
  await validators_1.CreateProductFallbackSchema.validateAsync(data);
408
- await this.validateQuotaFallbackInputAndOutput(data);
629
+ await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
409
630
  await Promise.all(data.options.map(async (d) => {
410
- const app = await this.fetchThirdPartyAppByAccessTag(d.app);
411
- if (!app) {
412
- throw new Error(`App with access tag ${d.app} not found`);
413
- }
414
- const version = app.versions.find((version) => version.tag === app.version);
415
- const action = version.actions.find((action) => action.tag === d.event);
416
- if (!action) {
417
- throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
418
- }
419
- if (d.healthcheck) {
420
- const action = version.actions.find((action) => action.tag === d.healthcheck);
421
- if (!d.check_interval) {
422
- d.check_interval = 10000;
631
+ if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
632
+ const app = await this.fetchThirdPartyAppByAccessTag(d.app);
633
+ if (!app) {
634
+ throw new Error(`App with access tag ${d.app} not found`);
423
635
  }
636
+ const version = app.versions.find((version) => version.tag === app.version);
637
+ const action = version.actions.find((action) => action.tag === d.event);
424
638
  if (!action) {
425
- throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
639
+ throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
640
+ }
641
+ if (d.healthcheck) {
642
+ const action = version.actions.find((action) => action.tag === d.healthcheck);
643
+ if (!d.check_interval) {
644
+ d.check_interval = 10000;
645
+ }
646
+ if (!action) {
647
+ throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
648
+ }
649
+ if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
650
+ throw new Error('Healthcheck action is expected to have no headers, body, params or query');
651
+ }
426
652
  }
427
653
  }
428
654
  d.last_checked = new Date();
@@ -431,83 +657,57 @@ class ProductsBuilderService {
431
657
  }));
432
658
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FALLBACK, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
433
659
  }
434
- else {
435
- throw new Error(`Quota with tag ${data.tag} already exists`);
436
- }
437
660
  }
438
661
  catch (e) {
439
662
  throw e;
440
663
  }
441
664
  }
442
665
  async updateFallback(tag, data) {
443
- /*try {
444
-
445
- if (!data.tag) {
446
- throw new Error('tag field is required');
447
- }
448
-
449
- if (this.fetchQuota(tag)) {
450
-
451
- if(data.tag && tag !== data.tag && this.fetchFallback(data.tag)) {
452
- throw new Error(`Fallback with new tag ${data.tag} already exists`)
666
+ try {
667
+ const fallback = this.fetchFallback(tag);
668
+ if (fallback) {
669
+ await validators_1.UpdateProductFallbackSchema.validateAsync(data);
670
+ if (data.options) {
671
+ await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
672
+ data.tag = tag;
673
+ await Promise.all(data.options.map(async (d) => {
674
+ if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
675
+ const app = await this.fetchThirdPartyAppByAccessTag(d.app);
676
+ if (!app) {
677
+ throw new Error(`App with access tag ${d.app} not found`);
678
+ }
679
+ const version = app.versions.find((version) => version.tag === app.version);
680
+ const action = version.actions.find((action) => action.tag === d.event);
681
+ if (!action) {
682
+ throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
683
+ }
684
+ if (d.healthcheck) {
685
+ const action = version.actions.find((action) => action.tag === d.healthcheck);
686
+ if (!d.check_interval) {
687
+ d.check_interval = 10000;
688
+ }
689
+ if (!action) {
690
+ throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
691
+ }
692
+ if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
693
+ throw new Error('Healthcheck action is expected to have no headers, body, params or query');
694
+ }
695
+ }
696
+ }
697
+ d.last_checked = new Date();
698
+ d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
699
+ d.last_available = true;
700
+ }));
701
+ }
702
+ await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, fallback), data), { component: enums_1.ProductComponents.FALLBACK, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
453
703
  }
454
-
455
- if(!data.tag) {
456
- data.tag = tag;
704
+ else {
705
+ throw new Error(`Fallback with tag ${data.tag} not found`);
457
706
  }
458
-
459
- await UpdateProductFallbackSchema.validateAsync(data);
460
-
461
- await this.validateQuotaFallbackInputAndOutput(data);
462
-
463
- await Promise.all(data.options.map(async (d) => {
464
-
465
- const app = await this.fetchThirdPartyAppByAccessTag(d.app);
466
-
467
- if (!app) {
468
- throw new Error(`App with access tag ${d.app} not found`)
469
- }
470
-
471
- const version = app.versions.find((version) => version.tag === app.version);
472
- const action = version.actions.find((action) => action.tag === d.event)
473
-
474
- if (!action) {
475
- throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`)
476
- }
477
-
478
- if (d.healthcheck) {
479
- const action = version.actions.find((action) => action.tag === d.healthcheck)
480
-
481
- if (!d.check_interval) {
482
- d.check_interval = 10000;
483
- }
484
-
485
- if (!action) {
486
- throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`)
487
- }
488
- }
489
-
490
- d.last_checked = new Date();
491
- d.provider_status = ProviderStatus.AVAILABLE;
492
- d.last_available = true;
493
- }))
494
-
495
- await this.productApi.updateProduct(
496
- this.product_id,
497
- {
498
- ...data,
499
- component: ProductComponents.FALLBACK,
500
- },
501
- this.getUserAccess(),
502
- );
503
-
504
- } else {
505
- throw new Error(`Quota with tag ${data.tag} already exists`)
506
- }
507
-
508
- } catch (e) {
509
- throw e;
510
- }*/
707
+ }
708
+ catch (e) {
709
+ throw e;
710
+ }
511
711
  }
512
712
  fetchFallback(tag) {
513
713
  return this.fetchFallbacks().find((data) => data.tag === tag);
@@ -960,6 +1160,8 @@ class ProductsBuilderService {
960
1160
  throw new Error(`App with access tag ${access_tag} not found`);
961
1161
  }
962
1162
  const version = app.versions.find((version) => version.tag === app.version);
1163
+ const status = await this.webhooksApi.fetchWebhooks({ access_tag, app_tag: app.tag, version: app.version }, this.getUserAccess());
1164
+ console.log(status);
963
1165
  if (!version) {
964
1166
  throw new Error(`Required app version not found`);
965
1167
  }
@@ -1206,7 +1408,7 @@ class ProductsBuilderService {
1206
1408
  if (!notificationTag || !messageTag) {
1207
1409
  throw new Error(`tag is expected to be defined as "notification_tag:message_tag"`);
1208
1410
  }
1209
- const notification = this.product.notifications.find((data) => data.tag === notificationTag);
1411
+ const notification = this.fetchNotification(notificationTag);
1210
1412
  if (!notification)
1211
1413
  throw new Error(`Notification ${notificationTag} not found`);
1212
1414
  const message = notification.messages.find((data) => data.tag === messageTag);