@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.
- package/dist/apps/services/app.service.js +4 -1
- package/dist/apps/services/app.service.js.map +1 -1
- package/dist/apps/utils/objects.utils.d.ts +1 -1
- package/dist/apps/utils/objects.utils.js +5 -3
- package/dist/apps/utils/objects.utils.js.map +1 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.js +28 -3
- package/dist/index.js.map +1 -1
- package/dist/logs/logs.service.js +0 -1
- package/dist/logs/logs.service.js.map +1 -1
- package/dist/logs/logs.types.d.ts +2 -0
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +7 -3
- package/dist/processor/services/processor.service.js +153 -86
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/utils/storage.util.js +0 -1
- package/dist/processor/utils/storage.util.js.map +1 -1
- package/dist/products/services/products.service.d.ts +11 -4
- package/dist/products/services/products.service.js +169 -45
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/utils/functions.utils.d.ts +1 -0
- package/dist/products/utils/functions.utils.js +11 -0
- package/dist/products/utils/functions.utils.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productFallback.validator.js +7 -1
- package/dist/products/validators/joi-validators/create.productFallback.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productQuota.validator.js +8 -2
- package/dist/products/validators/joi-validators/create.productQuota.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productFallback.validator.js +7 -2
- package/dist/products/validators/joi-validators/update.productFallback.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productQuota.validator.js +5 -1
- package/dist/products/validators/joi-validators/update.productQuota.validator.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +2 -2
- 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,
|
|
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
|
|
122
|
-
validateQuotaFallbackInput(option: IQuotaOptions | IFallbackOptions, input: Record<string, IFeatureInput
|
|
123
|
-
|
|
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,
|
|
361
|
-
|
|
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
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
382
|
-
|
|
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
|
-
|
|
424
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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(`
|
|
703
|
+
throw new Error(`Fallback with tag ${data.tag} not found`);
|
|
580
704
|
}
|
|
581
705
|
}
|
|
582
706
|
catch (e) {
|