@ductape/sdk 0.0.3-beta10 → 0.0.3-beta12

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 (33) hide show
  1. package/dist/apps/services/app.service.js +4 -1
  2. package/dist/apps/services/app.service.js.map +1 -1
  3. package/dist/apps/utils/objects.utils.d.ts +1 -1
  4. package/dist/apps/utils/objects.utils.js +5 -3
  5. package/dist/apps/utils/objects.utils.js.map +1 -1
  6. package/dist/index.d.ts +10 -4
  7. package/dist/index.js +28 -3
  8. package/dist/index.js.map +1 -1
  9. package/dist/logs/logs.service.js +0 -1
  10. package/dist/logs/logs.service.js.map +1 -1
  11. package/dist/logs/logs.types.d.ts +2 -0
  12. package/dist/logs/logs.types.js.map +1 -1
  13. package/dist/processor/services/processor.service.d.ts +7 -3
  14. package/dist/processor/services/processor.service.js +153 -86
  15. package/dist/processor/services/processor.service.js.map +1 -1
  16. package/dist/processor/utils/storage.util.js +0 -1
  17. package/dist/processor/utils/storage.util.js.map +1 -1
  18. package/dist/products/services/products.service.d.ts +11 -4
  19. package/dist/products/services/products.service.js +169 -45
  20. package/dist/products/services/products.service.js.map +1 -1
  21. package/dist/products/utils/functions.utils.d.ts +1 -0
  22. package/dist/products/utils/functions.utils.js +11 -0
  23. package/dist/products/utils/functions.utils.js.map +1 -1
  24. package/dist/products/validators/joi-validators/create.productFallback.validator.js +7 -1
  25. package/dist/products/validators/joi-validators/create.productFallback.validator.js.map +1 -1
  26. package/dist/products/validators/joi-validators/create.productQuota.validator.js +8 -2
  27. package/dist/products/validators/joi-validators/create.productQuota.validator.js.map +1 -1
  28. package/dist/products/validators/joi-validators/update.productFallback.validator.js +7 -2
  29. package/dist/products/validators/joi-validators/update.productFallback.validator.js.map +1 -1
  30. package/dist/products/validators/joi-validators/update.productQuota.validator.js +5 -1
  31. package/dist/products/validators/joi-validators/update.productQuota.validator.js.map +1 -1
  32. package/dist/types/productsBuilder.types.d.ts +2 -2
  33. package/package.json +1 -1
@@ -39,7 +39,6 @@ async function uploadBlobToCloud({ data, destinationPath, config, }) {
39
39
  if (typeof window !== 'undefined') {
40
40
  return null; // We're in a browser, don't load the PostgreSQL handler
41
41
  }
42
- console.log("JASMINE", data);
43
42
  const bufferData = Buffer.from(data, "base64");
44
43
  switch (config.provider) {
45
44
  case types_1.StorageProviders.AWS: {
@@ -1 +1 @@
1
- {"version":3,"file":"storage.util.js","sourceRoot":"","sources":["../../../src/processor/utils/storage.util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,8CAiEC;AAzED,uCAAkE;AAQ3D,KAAK,UAAU,iBAAiB,CAAC,EACpC,IAAI,EACJ,eAAe,EACf,MAAM,GACU;IAEhB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,CAAC,wDAAwD;IACzE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAE7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE/C,QAAQ,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,wBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YAExB,MAAM,GAAG,GAAG,wDAAa,SAAS,GAAC,CAAA;YAEnC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,SAAU,CAAC;YAC/E,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;gBAClB,WAAW;gBACX,eAAe;gBACf,MAAM;aACT,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG;gBACX,MAAM,EAAE,UAAU;gBAClB,GAAG,EAAE,eAAe;gBACpB,IAAI,EAAE,UAAU;aACnB,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACjD,OAAO,MAAM,CAAC,QAAQ,CAAC;QAC3B,CAAC;QAED,KAAK,wBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YAExB,MAAM,EAAE,OAAO,EAAE,GAAG,wDAAa,uBAAuB,GAAC,CAAC;YAC1D,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,SAAU,CAAC;YAC9D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAE1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,YAAY,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAO,UAA8B,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAExH,OAAO,QAAQ,UAAU,IAAI,eAAe,EAAE,CAAC;QACnD,CAAC;QAED,KAAK,wBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1B,MAAM,EAAE,iBAAiB,EAAE,GAAG,wDAAa,qBAAqB,GAAC,CAAC;YAClE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,WAAY,CAAC;YAChE,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;YACnF,MAAM,eAAe,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAC5E,MAAM,eAAe,GAAG,eAAe,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;YAE5E,4GAA4G;YAE5G,MAAM,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5D,OAAO,eAAe,CAAC,GAAG,CAAC;QAC/B,CAAC;QAED;YACI,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACvD,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"storage.util.js","sourceRoot":"","sources":["../../../src/processor/utils/storage.util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,8CA+DC;AAvED,uCAAkE;AAQ3D,KAAK,UAAU,iBAAiB,CAAC,EACpC,IAAI,EACJ,eAAe,EACf,MAAM,GACU;IAEhB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,CAAC,wDAAwD;IACzE,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE/C,QAAQ,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,wBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YAExB,MAAM,GAAG,GAAG,wDAAa,SAAS,GAAC,CAAA;YAEnC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,SAAU,CAAC;YAC/E,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;gBAClB,WAAW;gBACX,eAAe;gBACf,MAAM;aACT,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG;gBACX,MAAM,EAAE,UAAU;gBAClB,GAAG,EAAE,eAAe;gBACpB,IAAI,EAAE,UAAU;aACnB,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;YACjD,OAAO,MAAM,CAAC,QAAQ,CAAC;QAC3B,CAAC;QAED,KAAK,wBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;YAExB,MAAM,EAAE,OAAO,EAAE,GAAG,wDAAa,uBAAuB,GAAC,CAAC;YAC1D,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,SAAU,CAAC;YAC9D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAE1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,YAAY,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAO,UAA8B,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAExH,OAAO,QAAQ,UAAU,IAAI,eAAe,EAAE,CAAC;QACnD,CAAC;QAED,KAAK,wBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1B,MAAM,EAAE,iBAAiB,EAAE,GAAG,wDAAa,qBAAqB,GAAC,CAAC;YAClE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,WAAY,CAAC;YAChE,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;YACnF,MAAM,eAAe,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAC5E,MAAM,eAAe,GAAG,eAAe,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;YAE5E,4GAA4G;YAE5G,MAAM,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5D,OAAO,eAAe,CAAC,GAAG,CAAC;QAC/B,CAAC;QAED;YACI,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACvD,CAAC;AACL,CAAC"}
@@ -1,6 +1,7 @@
1
- import { IApp, IAppAccess, IAppAction, IAppWebhook, IVersion } from '../../types/appBuilder.types';
1
+ import { IApp, IAppAccess, IAppAction, IAppWebhook, ISample, IVersion } from '../../types/appBuilder.types';
2
2
  import { IBuilderInit } from '../../types/index.types';
3
3
  import { IActionDataParserInput, IActionRequest, ICreateProductsBuilder, IFeatureEvent, IFeatureInput, IFeatureSequence, IProduct, IProductApp, IProductCache, IProductDatabase, IProductDatabaseAction, IProductEnv, IProductFeature, IProductFunction, IProductJobs, IParseActionEventInput, IParseInputStringInput, IParseInputStringMetaData, IProductStorage, IDbActionRequest, INotificationRequest, IProductQuota, IProductFallback, IProductDatabaseMigration, IQuotaOptions, IFallbackOptions, IProductSession } from '../../types/productsBuilder.types';
4
+ import { KeyValuePair } from '../../imports/imports.types';
4
5
  import { IProductNotification, INotificationEnv, IProductNotificationTemplate, IProductMessageBroker, IProductMessageBrokerTopic } from '../../types/processor.types';
5
6
  import { IParsedSample } from '../../types/inputs.types';
6
7
  export interface IProductsBuilderService {
@@ -118,9 +119,15 @@ export default class ProductsBuilderService implements IProductsBuilderService {
118
119
  updateMessageBrokerTopic(data: Partial<IProductMessageBrokerTopic>): Promise<void>;
119
120
  fetchMessageBrokerTopic(tag: string, throwErrorIfExists?: boolean): IProductMessageBrokerTopic | null;
120
121
  fetchMessageBrokerTopics(messageBrokerTag: string): Array<IProductMessageBrokerTopic>;
121
- validateQuotaFallbackInputAndOutput(data: Partial<IProductQuota> | Partial<IProductFallback>): Promise<void>;
122
- validateQuotaFallbackInput(option: IQuotaOptions | IFallbackOptions, input: Record<string, IFeatureInput>): Promise<void>;
123
- validateQuotaFallbackOutput(option: IQuotaOptions | IFallbackOptions, pastResponse: Record<string, unknown> | null, input: Record<string, IFeatureInput>): Promise<void>;
122
+ validateQuotaFallbackInputAndOutput(data: Partial<IProductQuota> | Partial<IProductFallback>, type: string): Promise<void>;
123
+ validateQuotaFallbackInput(option: IQuotaOptions | IFallbackOptions, input: Record<string, IFeatureInput>, type: string): Promise<void>;
124
+ checkKeyValuesInput(keyValues: Array<KeyValuePair>, input: Record<string, IFeatureInput>, type: string): void;
125
+ checkActionQuotaFallbackInput(sample: ISample, obj: any, featureInput: Record<string, IFeatureInput>, type: string): void;
126
+ checkFuncArgsForInputs(value: string, input: Record<string, IFeatureInput>, type: string): void;
127
+ checkInput(value: string, input: Record<string, IFeatureInput>, type: string): void;
128
+ validateQuotaFallbackOutput(option: IQuotaOptions | IFallbackOptions, pastResponse: Record<string, unknown> | null, input: Record<string, IFeatureInput>, type: string): Promise<void>;
129
+ checkFuncArgsForResponse(value: string, output: Record<string, unknown>, input: Record<string, IFeatureInput>, type: string): void;
130
+ checkResponse(value: string, output: Record<string, unknown>, input: Record<string, IFeatureInput>, type: string): void;
124
131
  createQuota(data: Partial<IProductQuota>): Promise<void>;
125
132
  updateQuota(tag: string, data: Partial<IProductQuota>): Promise<void>;
126
133
  fetchQuota(tag: string): IProductQuota | null;
@@ -330,15 +330,15 @@ class ProductsBuilderService {
330
330
  throw new Error(`Message Broker ${messageBrokerTag} not found`);
331
331
  return messageBroker.topics;
332
332
  }
333
- async validateQuotaFallbackInputAndOutput(data) {
333
+ async validateQuotaFallbackInputAndOutput(data, type) {
334
334
  const input = data.input;
335
335
  await Promise.all(data.options.map(async (d, index) => {
336
- await this.validateQuotaFallbackInput(d, input);
336
+ await this.validateQuotaFallbackInput(d, input, type);
337
337
  const pastOutput = index > 0 ? data.options[index - 1].output : null;
338
- await this.validateQuotaFallbackOutput(d, pastOutput, input);
338
+ await this.validateQuotaFallbackOutput(d, pastOutput, input, type);
339
339
  }));
340
340
  }
341
- async validateQuotaFallbackInput(option, input) {
341
+ async validateQuotaFallbackInput(option, input, type) {
342
342
  if (option.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
343
343
  const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
344
344
  if (!appData) {
@@ -350,45 +350,171 @@ class ProductsBuilderService {
350
350
  if (!appData) {
351
351
  throw new Error(`Action ${option.event} not found in ${option.app} version ${version}`);
352
352
  }
353
- await this.validateActionDataInput({ input }, action, option.input, 0, 0);
353
+ //await this.validateActionDataInput({ input }, action, option.input, 0, 0);
354
+ // const keyValues = traverseObject(input.option);
355
+ //query
356
+ this.checkActionQuotaFallbackInput(action.query, option.input.query, input, 'query');
357
+ //headers
358
+ this.checkActionQuotaFallbackInput(action.headers, option.input.headers, input, 'headers');
359
+ // params
360
+ this.checkActionQuotaFallbackInput(action.params, option.input.params, input, 'params');
361
+ //body
362
+ this.checkActionQuotaFallbackInput(action.body, option.input.body, input, 'body');
354
363
  }
355
364
  else {
356
365
  const feature = this.fetchFeature(option.event);
357
366
  if (!feature) {
358
367
  throw new Error(`Feature ${option.event} not found`);
359
368
  }
360
- (0, objects_utils_2.validateObjectKeys)(feature.input, option.input);
361
- const keyValues = (0, objects_utils_1.traverseObject)(option.input);
362
- for (let keyValue of keyValues) {
363
- const { key, value } = keyValue;
364
- if (!value.startsWith('$Input{')) {
365
- //throw new Error(`Feature input ${value} is invalid, all feature Inputs are expected to start with $Input{}`);
366
- }
367
- }
369
+ const map = (0, functions_utils_1.convertInputToValueMap)(feature.input);
370
+ (0, objects_utils_2.validateObjectKeys)(map, option.input, '', 'option input', 'feature input definition');
368
371
  }
372
+ const keyValues = (0, objects_utils_1.traverseObject)(option.input);
373
+ this.checkKeyValuesInput(keyValues, input, type);
369
374
  this.isQuotaFallbackInput = false;
370
375
  }
371
- async validateQuotaFallbackOutput(option, pastResponse, input) {
372
- const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
373
- if (!appData) {
374
- throw new Error(`App ${option.app} not found`);
376
+ checkKeyValuesInput(keyValues, input, type) {
377
+ for (let keyValue of keyValues) {
378
+ const { key, value } = keyValue;
379
+ if (!String(value).startsWith('$')) {
380
+ }
381
+ else if (String(value).startsWith('$Auth{')) {
382
+ // TODO: validate auth input later
383
+ }
384
+ else if (String(value).startsWith('$') && !String(value).startsWith('$Input{')) {
385
+ this.checkFuncArgsForInputs(String(value).trim(), input, type);
386
+ }
387
+ else if (!String(value).startsWith('$Input{')) {
388
+ throw new Error(`Feature input ${value} is invalid, all feature Inputs are expected to start with $Input{}`);
389
+ }
390
+ else {
391
+ this.checkInput(String(value).trim(), input, type);
392
+ }
393
+ }
394
+ }
395
+ checkActionQuotaFallbackInput(sample, obj, featureInput, type) {
396
+ const data = (0, objects_utils_1.traverseObject)(obj);
397
+ //compare obj keys to sample keys
398
+ (0, objects_utils_2.validateObjectKeys)(sample.sample ? JSON.parse(String(sample.sample)) : {}, obj, '', `action ${type} input`, `action ${type} input sample`);
399
+ // check if values in data can be found inside featureInput
400
+ this.checkKeyValuesInput(data, featureInput, type);
401
+ }
402
+ checkFuncArgsForInputs(value, input, type) {
403
+ const isFunc = (0, functions_utils_1.startsWithFunctionAndEndsWithParen)(value);
404
+ if (!isFunc) {
405
+ throw new Error(`Invalid function call ${value}`);
406
+ }
407
+ const funcArgs = (0, functions_utils_1.extractFunctionAndArgs)(value);
408
+ if (funcArgs && funcArgs.args.length) {
409
+ funcArgs.args.map((arg) => {
410
+ const args = arg.trim().split(',');
411
+ args.map((argz) => {
412
+ const arg = argz.trim();
413
+ if (arg.startsWith('$') && !arg.startsWith('$Input{')) {
414
+ this.checkFuncArgsForInputs(arg, input, type);
415
+ }
416
+ else if (arg.startsWith('$Input{')) {
417
+ this.checkInput(arg, input, type);
418
+ }
419
+ });
420
+ });
375
421
  }
376
- const { actions } = appData.versions.find((data) => data.tag === version);
377
- const action = actions.find((data) => data.tag === option.event);
378
- if (!appData) {
379
- throw new Error(`Action ${event} not found in ${option.app} version ${version}`);
422
+ }
423
+ checkInput(value, input, type) {
424
+ const stages = this.extractStages(value);
425
+ if (stages.length > 1) {
426
+ throw new Error(`Invalid input ${value}, nested locators not allowed in $Input`);
380
427
  }
381
- const response = action.responses.find((item) => item.success === true);
382
- // fetch success result
383
- if (!response) {
384
- throw new Error(`event ${event} does not have a success response`);
428
+ if (!input[stages[0]]) {
429
+ throw new Error(`${value} not found in ${type} input definition`);
385
430
  }
431
+ }
432
+ async validateQuotaFallbackOutput(option, pastResponse, input, type) {
386
433
  if (pastResponse) {
387
- (0, objects_utils_2.validateObjectKeys)(option.output, pastResponse);
434
+ (0, objects_utils_2.validateObjectKeys)(option.output, pastResponse, `previous outputs`, `${option.event} ${type} output`);
435
+ }
436
+ if (option.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
437
+ const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
438
+ if (!appData) {
439
+ throw new Error(`App ${option.app} not found`);
440
+ }
441
+ const { actions } = appData.versions.find((data) => data.tag === version);
442
+ const action = actions.find((data) => data.tag === option.event);
443
+ if (!appData) {
444
+ throw new Error(`Action ${event} not found in ${option.app} version ${version}`);
445
+ }
446
+ const response = action.responses.find((item) => item.success === true);
447
+ // fetch success result
448
+ if (!response) {
449
+ throw new Error(`event ${event} does not have a success response`);
450
+ }
451
+ // validate that each output item starts with response or Input and then validate the stages are valid;
452
+ }
453
+ else {
454
+ // fetch feature
455
+ const feature = this.fetchFeature(option.event);
456
+ if (!feature) {
457
+ throw new Error(`Feature ${option.event} not found`);
458
+ }
459
+ const { output } = feature;
460
+ const keyValues = (0, objects_utils_1.traverseObject)(option.output);
461
+ for (let keyValue of keyValues) {
462
+ const { key, value } = keyValue;
463
+ if (!value.startsWith('$')) {
464
+ }
465
+ else if (value.startsWith('$') && !value.startsWith('$Response{') && !value.startsWith('$Input')) {
466
+ this.checkFuncArgsForResponse(value.trim(), output, input, type);
467
+ }
468
+ else if (!value.startsWith('$Response{') && !value.startsWith('$Input{')) {
469
+ throw new Error(`Feature output ${value} is invalid, all feature outputs for ${type} are expected to start with $Response or $Input{}`);
470
+ }
471
+ else if (value.startsWith('$Response')) {
472
+ this.checkResponse(value.trim(), output, input, type);
473
+ }
474
+ else if (value.startsWith('$Input')) {
475
+ this.checkInput(value, input, type);
476
+ }
477
+ }
388
478
  }
389
479
  // validate that each response matches the expected format
390
480
  /**await this.validateActionResponse(response, res)*/
391
481
  }
482
+ checkFuncArgsForResponse(value, output, input, type) {
483
+ const isFunc = (0, functions_utils_1.startsWithFunctionAndEndsWithParen)(value);
484
+ if (!isFunc) {
485
+ throw new Error(`Invalid function call ${value}`);
486
+ }
487
+ const funcArgs = (0, functions_utils_1.extractFunctionAndArgs)(value);
488
+ if (funcArgs && funcArgs.args.length) {
489
+ funcArgs.args.map((arg) => {
490
+ const args = arg.trim().split(',');
491
+ args.map((argz) => {
492
+ const arg = argz.trim();
493
+ if (arg.startsWith('$') && !arg.startsWith('$Response{') && !arg.startsWith('$Input{')) {
494
+ this.checkFuncArgsForResponse(arg, output, input, type);
495
+ }
496
+ else if (arg.startsWith('$Response{')) {
497
+ this.checkResponse(arg, output, input, type);
498
+ }
499
+ else if (arg.startsWith('$Input{')) {
500
+ this.checkInput(arg, input, type);
501
+ }
502
+ });
503
+ });
504
+ }
505
+ }
506
+ checkResponse(value, output, input, type) {
507
+ const stages = this.extractStages(value);
508
+ let current = output;
509
+ for (const stage of stages) {
510
+ if (current && typeof current === 'object' && stage in current) {
511
+ current = current[stage];
512
+ }
513
+ else {
514
+ throw new Error(`${value} not found in ${type} response definition`);
515
+ }
516
+ }
517
+ }
392
518
  async createQuota(data) {
393
519
  try {
394
520
  if (!data.tag) {
@@ -396,7 +522,7 @@ class ProductsBuilderService {
396
522
  }
397
523
  if (!this.fetchQuota(data.tag)) {
398
524
  await validators_1.CreateProductQuotaSchema.validateAsync(data);
399
- await this.validateQuotaFallbackInputAndOutput(data);
525
+ await this.validateQuotaFallbackInputAndOutput(data, 'quota');
400
526
  data.total_quota = 0;
401
527
  data.total_init = 0;
402
528
  await Promise.all(data.options.map(async (d) => {
@@ -419,9 +545,9 @@ class ProductsBuilderService {
419
545
  if (!action) {
420
546
  throw new Error(`Cannot find healthcheck action ${d.healthcheck} on app ${app.tag} version ${app.version}`);
421
547
  }
422
- }
423
- if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
424
- throw new Error('Healthcheck action is expected to have no headers, body, params or query');
548
+ if (action.headers.data.length > 0 || action.body.data.length > 0 || action.params.data.length > 0 || action.query.data.length > 0) {
549
+ throw new Error('Healthcheck action is expected to have no headers, body, params or query');
550
+ }
425
551
  }
426
552
  }
427
553
  d.last_checked = new Date();
@@ -430,9 +556,6 @@ class ProductsBuilderService {
430
556
  }));
431
557
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.QUOTA, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
432
558
  }
433
- else {
434
- throw new Error(`Quota with tag ${data.tag} already exists`);
435
- }
436
559
  }
437
560
  catch (e) {
438
561
  throw e;
@@ -440,12 +563,14 @@ class ProductsBuilderService {
440
563
  }
441
564
  async updateQuota(tag, data) {
442
565
  try {
443
- if (this.fetchQuota(tag)) {
566
+ const quota = this.fetchQuota(tag);
567
+ if (quota) {
444
568
  await validators_1.UpdateProductQuotaSchema.validateAsync(data);
445
569
  if (data.options) {
446
- await this.validateQuotaFallbackInputAndOutput(data);
570
+ await this.validateQuotaFallbackInputAndOutput(data, 'quota');
447
571
  data.total_quota = 0;
448
572
  data.total_init = 0;
573
+ data.tag = tag;
449
574
  await Promise.all(data.options.map(async (d) => {
450
575
  data.total_quota += d.quota;
451
576
  if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
@@ -476,7 +601,7 @@ class ProductsBuilderService {
476
601
  d.last_available = true;
477
602
  }));
478
603
  }
479
- await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.QUOTA, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
604
+ 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());
480
605
  }
481
606
  else {
482
607
  throw new Error(`Quota with tag ${data.tag} not found`);
@@ -497,9 +622,9 @@ class ProductsBuilderService {
497
622
  if (!data.tag) {
498
623
  throw new Error('tag field is required');
499
624
  }
500
- if (!this.fetchQuota(data.tag)) {
625
+ if (!this.fetchFallback(data.tag)) {
501
626
  await validators_1.CreateProductFallbackSchema.validateAsync(data);
502
- await this.validateQuotaFallbackInputAndOutput(data);
627
+ await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
503
628
  await Promise.all(data.options.map(async (d) => {
504
629
  if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
505
630
  const app = await this.fetchThirdPartyAppByAccessTag(d.app);
@@ -530,9 +655,6 @@ class ProductsBuilderService {
530
655
  }));
531
656
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FALLBACK, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
532
657
  }
533
- else {
534
- throw new Error(`Quota with tag ${data.tag} already exists`);
535
- }
536
658
  }
537
659
  catch (e) {
538
660
  throw e;
@@ -540,10 +662,12 @@ class ProductsBuilderService {
540
662
  }
541
663
  async updateFallback(tag, data) {
542
664
  try {
543
- if (this.fetchFallback(tag)) {
665
+ const fallback = this.fetchFallback(tag);
666
+ if (fallback) {
544
667
  await validators_1.UpdateProductFallbackSchema.validateAsync(data);
545
668
  if (data.options) {
546
- await this.validateQuotaFallbackInputAndOutput(data);
669
+ await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
670
+ data.tag = tag;
547
671
  await Promise.all(data.options.map(async (d) => {
548
672
  if (d.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
549
673
  const app = await this.fetchThirdPartyAppByAccessTag(d.app);
@@ -573,10 +697,10 @@ class ProductsBuilderService {
573
697
  d.last_available = true;
574
698
  }));
575
699
  }
576
- await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FALLBACK, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
700
+ 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());
577
701
  }
578
702
  else {
579
- throw new Error(`Quota with tag ${data.tag} not found`);
703
+ throw new Error(`Fallback with tag ${data.tag} not found`);
580
704
  }
581
705
  }
582
706
  catch (e) {