@ductape/sdk 0.1.26 → 0.1.27
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/README.md +83 -52
- package/dist/agents/agent-context.d.ts +1 -1
- package/dist/agents/agent-context.js +1 -1
- package/dist/agents/agent-context.js.map +1 -1
- package/dist/agents/agents.service.js +4 -4
- package/dist/agents/agents.service.js.map +1 -1
- package/dist/agents/types/agents.types.d.ts +6 -6
- package/dist/api/services/featureApi.service.d.ts +199 -0
- package/dist/api/services/featureApi.service.js +201 -0
- package/dist/api/services/featureApi.service.js.map +1 -0
- package/dist/api/services/processorApi.service.d.ts +2 -2
- package/dist/api/services/processorApi.service.js +1 -1
- package/dist/api/services/productsApi.service.d.ts +6 -6
- package/dist/api/services/productsApi.service.js +3 -3
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/urls.d.ts +12 -12
- package/dist/api/urls.js +22 -22
- package/dist/api/urls.js.map +1 -1
- package/dist/apps/validators/index.d.ts +5 -1
- package/dist/apps/validators/index.js +9 -1
- package/dist/apps/validators/index.js.map +1 -1
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +1 -0
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +1 -0
- package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.d.ts +1 -0
- package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js +1 -0
- package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +1 -0
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +1 -0
- package/dist/apps/validators/joi-validators/update.appWebhook.validator.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.d.ts +1 -0
- package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js +1 -0
- package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js.map +1 -1
- package/dist/brokers/brokers.service.d.ts +2 -2
- package/dist/brokers/brokers.service.js +2 -2
- package/dist/brokers/brokers.service.js.map +1 -1
- package/dist/brokers/types/index.d.ts +1 -1
- package/dist/cloud/cloud-database-link.util.js +22 -3
- package/dist/cloud/cloud-database-link.util.js.map +1 -1
- package/dist/cloud/cloud-service-map.util.js +6 -5
- package/dist/cloud/cloud-service-map.util.js.map +1 -1
- package/dist/cloud/index.d.ts +1 -1
- package/dist/cloud/index.js +3 -1
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/types/cloud.types.d.ts +1 -1
- package/dist/cloud/vpc-connector-connect.util.d.ts +11 -2
- package/dist/cloud/vpc-connector-connect.util.js +7 -0
- package/dist/cloud/vpc-connector-connect.util.js.map +1 -1
- package/dist/cloud/vpc-connector-tunnel.client.d.ts +26 -0
- package/dist/cloud/vpc-connector-tunnel.client.js +70 -0
- package/dist/cloud/vpc-connector-tunnel.client.js.map +1 -1
- package/dist/database/adapters/mysql.adapter.js +15 -0
- package/dist/database/adapters/mysql.adapter.js.map +1 -1
- package/dist/database/adapters/postgresql.adapter.js +11 -55
- package/dist/database/adapters/postgresql.adapter.js.map +1 -1
- package/dist/database/databases.service.d.ts +3 -3
- package/dist/database/databases.service.js +18 -18
- package/dist/database/databases.service.js.map +1 -1
- package/dist/database/index.d.ts +1 -1
- package/dist/database/triggers/trigger-processor.d.ts +7 -7
- package/dist/database/triggers/trigger-processor.js +17 -17
- package/dist/database/triggers/trigger-processor.js.map +1 -1
- package/dist/database/types/connection.interface.d.ts +0 -2
- package/dist/database/types/index.d.ts +1 -1
- package/dist/database/types/trigger.interface.d.ts +9 -9
- package/dist/database/types/trigger.interface.js +3 -3
- package/dist/database/types/trigger.interface.js.map +1 -1
- package/dist/features/feature-builder.d.ts +70 -0
- package/dist/features/feature-builder.js +348 -0
- package/dist/features/feature-builder.js.map +1 -0
- package/dist/features/feature-executor.d.ts +289 -0
- package/dist/features/feature-executor.js +2444 -0
- package/dist/features/feature-executor.js.map +1 -0
- package/dist/features/features.service.d.ts +412 -0
- package/dist/features/features.service.js +2222 -0
- package/dist/features/features.service.js.map +1 -0
- package/dist/features/index.d.ts +30 -0
- package/dist/features/index.js +64 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/types/features.types.d.ts +1081 -0
- package/dist/features/types/features.types.js +13 -0
- package/dist/features/types/features.types.js.map +1 -0
- package/dist/features/types/index.d.ts +6 -0
- package/dist/features/types/index.js +23 -0
- package/dist/features/types/index.js.map +1 -0
- package/dist/index.d.ts +35 -48
- package/dist/index.js +48 -63
- package/dist/index.js.map +1 -1
- package/dist/init.interface.d.ts +1 -11
- package/dist/inputs/inputs.service.d.ts +4 -4
- package/dist/inputs/inputs.service.js.map +1 -1
- package/dist/introspect/index.d.ts +31 -0
- package/dist/introspect/index.js +168 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/types.d.ts +3 -3
- package/dist/logs/logs.service.d.ts +0 -3
- package/dist/logs/logs.service.js +1 -4
- package/dist/logs/logs.service.js.map +1 -1
- package/dist/logs/logs.types.d.ts +4 -7
- package/dist/logs/logs.types.js +2 -3
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +27 -26
- package/dist/processor/services/processor.service.js +71 -72
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/processor/utils/processor.utils.d.ts +2 -2
- package/dist/processor/utils/processor.utils.js.map +1 -1
- package/dist/products/bootstrap-cache.d.ts +2 -2
- package/dist/products/bootstrap-cache.js +3 -3
- package/dist/products/bootstrap-cache.js.map +1 -1
- package/dist/products/services/products.service.d.ts +32 -57
- package/dist/products/services/products.service.js +44 -397
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/index.d.ts +1 -3
- package/dist/products/validators/index.js +1 -5
- package/dist/products/validators/index.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productDatabase.validator.js +1 -1
- package/dist/products/validators/joi-validators/create.productDatabase.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productFeature.validator.d.ts +1 -7
- package/dist/products/validators/joi-validators/create.productFeature.validator.js +6 -61
- package/dist/products/validators/joi-validators/create.productFeature.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productDatabase.validator.js +23 -27
- package/dist/products/validators/joi-validators/update.productDatabase.validator.js.map +1 -1
- package/dist/resilience/fallback.service.js +19 -41
- package/dist/resilience/fallback.service.js.map +1 -1
- package/dist/resilience/healthcheck.service.d.ts +5 -5
- package/dist/resilience/healthcheck.service.js +26 -26
- package/dist/resilience/healthcheck.service.js.map +1 -1
- package/dist/resilience/quota.service.js +17 -27
- package/dist/resilience/quota.service.js.map +1 -1
- package/dist/resilience/resilience-execution.utils.d.ts +2 -2
- package/dist/resilience/resilience-execution.utils.js +7 -7
- package/dist/resilience/resilience-execution.utils.js.map +1 -1
- package/dist/resilience/resilience.service.js +14 -30
- package/dist/resilience/resilience.service.js.map +1 -1
- package/dist/resilience/types/index.d.ts +20 -23
- package/dist/resilience/types/index.js +2 -3
- package/dist/resilience/types/index.js.map +1 -1
- package/dist/types/enums.d.ts +1 -2
- package/dist/types/enums.js +1 -2
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.types.d.ts +3 -4
- package/dist/types/index.types.js +2 -2
- package/dist/types/index.types.js.map +1 -1
- package/dist/types/logs.types.d.ts +0 -1
- package/dist/types/logs.types.js.map +1 -1
- package/dist/types/processor.types.d.ts +11 -13
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/productsBuilder.types.d.ts +52 -58
- package/dist/types/productsBuilder.types.js +57 -55
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/package.json +5 -2
|
@@ -265,10 +265,10 @@ class ProductsBuilderService {
|
|
|
265
265
|
option.check_interval = 10000;
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
|
-
/** Validate a quota/fallback action provider (app action or product
|
|
268
|
+
/** Validate a quota/fallback action provider (app action or product feature). */
|
|
269
269
|
async validateQuotaFallbackProvider(option) {
|
|
270
270
|
var _a;
|
|
271
|
-
if (option.type !== productsBuilder_types_1.
|
|
271
|
+
if (option.type !== productsBuilder_types_1.StepEventTypes.ACTION)
|
|
272
272
|
return;
|
|
273
273
|
if ((_a = option.app) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
274
274
|
const app = await this.fetchThirdPartyAppByAccessTag(option.app);
|
|
@@ -282,9 +282,9 @@ class ProductsBuilderService {
|
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
else {
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
287
|
-
throw new Error(`
|
|
285
|
+
const feature = await this.fetchFeature(option.event);
|
|
286
|
+
if (!feature) {
|
|
287
|
+
throw new Error(`Feature not found on product`);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
if (option.healthcheck) {
|
|
@@ -309,7 +309,7 @@ class ProductsBuilderService {
|
|
|
309
309
|
/**
|
|
310
310
|
* Create a healthcheck from a schema (e.g. from resilience health.define/create).
|
|
311
311
|
* Persists as product component so processor healthcheck workers and health.list/fetch see it.
|
|
312
|
-
* Env inputs (probe/action/
|
|
312
|
+
* Env inputs (probe/action/feature input) are encrypted with the product private key using
|
|
313
313
|
* SHA-256 key derivation + AES (see processor.utils encrypt/decrypt).
|
|
314
314
|
*/
|
|
315
315
|
async createHealthcheckFromSchema(schema) {
|
|
@@ -372,13 +372,13 @@ class ProductsBuilderService {
|
|
|
372
372
|
let size = 2;
|
|
373
373
|
let data;
|
|
374
374
|
switch (type) {
|
|
375
|
-
case productsBuilder_types_1.
|
|
375
|
+
case productsBuilder_types_1.StepEventTypes.DB_ACTION:
|
|
376
376
|
const action = await this.fetchDatabaseAction(tag);
|
|
377
377
|
if (!action)
|
|
378
378
|
throw new Error(`DB Action ${tag} not found`);
|
|
379
379
|
data = useData ? action.data : action.filterData;
|
|
380
380
|
break;
|
|
381
|
-
case productsBuilder_types_1.
|
|
381
|
+
case productsBuilder_types_1.StepEventTypes.NOTIFICATION:
|
|
382
382
|
size = 3;
|
|
383
383
|
const stage3Str = String(stages[3]);
|
|
384
384
|
if (!stages[3] || (stage3Str !== 'push' && stage3Str !== 'callback' && stage3Str !== 'email')) {
|
|
@@ -400,8 +400,8 @@ class ProductsBuilderService {
|
|
|
400
400
|
default:
|
|
401
401
|
throw new Error(`Type ${type} not handled`);
|
|
402
402
|
}
|
|
403
|
-
if (selector.startsWith('$Filter') && type !== productsBuilder_types_1.
|
|
404
|
-
throw new Error(`Filter cannot be used for ${type} in ${selector} only usable in ${productsBuilder_types_1.
|
|
403
|
+
if (selector.startsWith('$Filter') && type !== productsBuilder_types_1.StepEventTypes.DB_ACTION) {
|
|
404
|
+
throw new Error(`Filter cannot be used for ${type} in ${selector} only usable in ${productsBuilder_types_1.StepEventTypes.DB_ACTION}`);
|
|
405
405
|
}
|
|
406
406
|
const selectorArray = stages.slice(size);
|
|
407
407
|
let parent_key = '';
|
|
@@ -607,13 +607,13 @@ class ProductsBuilderService {
|
|
|
607
607
|
}
|
|
608
608
|
}
|
|
609
609
|
/**
|
|
610
|
-
* Bootstrap
|
|
610
|
+
* Bootstrap feature - fetch all action/notification/storage data for multiple steps in one API call
|
|
611
611
|
*/
|
|
612
|
-
async
|
|
612
|
+
async bootstrapFeature(params) {
|
|
613
613
|
try {
|
|
614
614
|
const auth = this.getUserAccess();
|
|
615
|
-
return await this.cachedBootstrap('workflow', [params.product_tag, params.env_slug, (0, bootstrap_cache_1.
|
|
616
|
-
const result = await this.productApi.
|
|
615
|
+
return await this.cachedBootstrap('workflow', [params.product_tag, params.env_slug, (0, bootstrap_cache_1.hashFeatureSteps)(params.steps)], async () => {
|
|
616
|
+
const result = await this.productApi.bootstrapFeature(Object.assign(Object.assign({}, params), { workspace_id: auth.workspace_id }), auth);
|
|
617
617
|
if (result && typeof result === 'object') {
|
|
618
618
|
for (const stepTag of Object.keys(result)) {
|
|
619
619
|
const data = result[stepTag];
|
|
@@ -1007,7 +1007,7 @@ class ProductsBuilderService {
|
|
|
1007
1007
|
}));
|
|
1008
1008
|
}
|
|
1009
1009
|
async validateQuotaFallbackInput(option, input, type) {
|
|
1010
|
-
if (option.type === productsBuilder_types_1.
|
|
1010
|
+
if (option.type === productsBuilder_types_1.StepEventTypes.ACTION) {
|
|
1011
1011
|
const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
|
|
1012
1012
|
if (!appData) {
|
|
1013
1013
|
throw new Error(`App ${option.app} not found`);
|
|
@@ -1030,12 +1030,7 @@ class ProductsBuilderService {
|
|
|
1030
1030
|
this.checkActionQuotaFallbackInput(action.body, option.input.body, input, 'body');
|
|
1031
1031
|
}
|
|
1032
1032
|
else {
|
|
1033
|
-
|
|
1034
|
-
if (!feature) {
|
|
1035
|
-
throw new Error(`Feature ${option.event} not found`);
|
|
1036
|
-
}
|
|
1037
|
-
const map = (0, functions_utils_1.convertInputToValueMap)(feature.input);
|
|
1038
|
-
(0, objects_utils_2.validateObjectKeys)(map, option.input, '', 'option input', 'feature input definition');
|
|
1033
|
+
throw new Error(`Unsupported quota/fallback option type for event ${option.event}: only ${productsBuilder_types_1.StepEventTypes.ACTION} is supported`);
|
|
1039
1034
|
}
|
|
1040
1035
|
const keyValues = (0, objects_utils_1.traverseObject)(option.input);
|
|
1041
1036
|
this.checkKeyValuesInput(keyValues, input, type);
|
|
@@ -1101,7 +1096,7 @@ class ProductsBuilderService {
|
|
|
1101
1096
|
if (pastResponse) {
|
|
1102
1097
|
(0, objects_utils_2.validateObjectKeys)(option.output, pastResponse, `previous outputs`, `${option.event} ${type} output`);
|
|
1103
1098
|
}
|
|
1104
|
-
if (option.type === productsBuilder_types_1.
|
|
1099
|
+
if (option.type === productsBuilder_types_1.StepEventTypes.ACTION) {
|
|
1105
1100
|
const _a = await this.fetchThirdPartyAppByAccessTag(option.app), { version } = _a, appData = __rest(_a, ["version"]);
|
|
1106
1101
|
if (!appData) {
|
|
1107
1102
|
throw new Error(`App ${option.app} not found`);
|
|
@@ -1119,30 +1114,7 @@ class ProductsBuilderService {
|
|
|
1119
1114
|
// validate that each output item starts with response or Input and then validate the stages are valid;
|
|
1120
1115
|
}
|
|
1121
1116
|
else {
|
|
1122
|
-
|
|
1123
|
-
const feature = await this.fetchFeature(option.event);
|
|
1124
|
-
if (!feature) {
|
|
1125
|
-
throw new Error(`Feature ${option.event} not found`);
|
|
1126
|
-
}
|
|
1127
|
-
const { output } = feature;
|
|
1128
|
-
const keyValues = (0, objects_utils_1.traverseObject)(option.output);
|
|
1129
|
-
for (let keyValue of keyValues) {
|
|
1130
|
-
const { key, value } = keyValue;
|
|
1131
|
-
if (!value.startsWith('$')) {
|
|
1132
|
-
}
|
|
1133
|
-
else if (value.startsWith('$') && !value.startsWith('$Response{') && !value.startsWith('$Input')) {
|
|
1134
|
-
this.checkFuncArgsForResponse(value.trim(), output, input, type);
|
|
1135
|
-
}
|
|
1136
|
-
else if (!value.startsWith('$Response{') && !value.startsWith('$Input{')) {
|
|
1137
|
-
throw new Error(`Feature output ${value} is invalid, all feature outputs for ${type} are expected to start with $Response or $Input{}`);
|
|
1138
|
-
}
|
|
1139
|
-
else if (value.startsWith('$Response')) {
|
|
1140
|
-
this.checkResponse(value.trim(), output, input, type);
|
|
1141
|
-
}
|
|
1142
|
-
else if (value.startsWith('$Input')) {
|
|
1143
|
-
this.checkInput(value, input, type);
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1117
|
+
throw new Error(`Unsupported quota/fallback option type for event ${option.event}: only ${productsBuilder_types_1.StepEventTypes.ACTION} is supported`);
|
|
1146
1118
|
}
|
|
1147
1119
|
// validate that each response matches the expected format
|
|
1148
1120
|
/**await this.validateActionResponse(response, res)*/
|
|
@@ -3279,71 +3251,6 @@ class ProductsBuilderService {
|
|
|
3279
3251
|
throw e;
|
|
3280
3252
|
}
|
|
3281
3253
|
}
|
|
3282
|
-
validateFeatureSequence(array) {
|
|
3283
|
-
// Validate uniqueness of sequence_tag
|
|
3284
|
-
const uniqueTags = new Set();
|
|
3285
|
-
for (const item of array) {
|
|
3286
|
-
if (uniqueTags.has(item.tag)) {
|
|
3287
|
-
throw new Error(`Duplicate sequence_tag found: ${item.tag}`);
|
|
3288
|
-
}
|
|
3289
|
-
uniqueTags.add(item.tag);
|
|
3290
|
-
}
|
|
3291
|
-
// Validate levels are in order starting from 0
|
|
3292
|
-
/*let expectedLevel = 0;
|
|
3293
|
-
for (const item of array) {
|
|
3294
|
-
if (item.level !== expectedLevel) {
|
|
3295
|
-
throw new Error(`Invalid level found: expected ${expectedLevel}, found ${item.level}`);
|
|
3296
|
-
}
|
|
3297
|
-
expectedLevel++;
|
|
3298
|
-
}*/
|
|
3299
|
-
}
|
|
3300
|
-
validateUniqueEventTags(data) {
|
|
3301
|
-
// TODO: this might not be necessary o
|
|
3302
|
-
const eventTagsSet = new Set(); // TODO: this might have to be moved to line 658
|
|
3303
|
-
data.sequence.forEach((sequence) => {
|
|
3304
|
-
sequence.events.forEach((data) => {
|
|
3305
|
-
const { event } = data;
|
|
3306
|
-
if (eventTagsSet.has(event)) {
|
|
3307
|
-
throw new Error(`Duplicate event_tag found: ${event}`);
|
|
3308
|
-
}
|
|
3309
|
-
eventTagsSet.add(event);
|
|
3310
|
-
});
|
|
3311
|
-
});
|
|
3312
|
-
}
|
|
3313
|
-
async validateFeatureData(data) {
|
|
3314
|
-
const { sequence } = data;
|
|
3315
|
-
this.validateUniqueEventTags(data); // TODO: this might be unnecessary
|
|
3316
|
-
this.validateFeatureSequence(sequence);
|
|
3317
|
-
const promises = sequence.map((obj, sequence_index) => {
|
|
3318
|
-
const { events, parents } = obj;
|
|
3319
|
-
if (parents && parents.length) {
|
|
3320
|
-
this.validateSequenceParents(parents, sequence_index, sequence);
|
|
3321
|
-
}
|
|
3322
|
-
return Promise.all(events.map((event, event_index) => this.validateEvent(data, sequence_index, event, event_index)));
|
|
3323
|
-
});
|
|
3324
|
-
const results = await Promise.allSettled(promises.flat());
|
|
3325
|
-
const errors = results
|
|
3326
|
-
.filter((result) => result.status === 'rejected')
|
|
3327
|
-
.map((result) => result.reason);
|
|
3328
|
-
if (errors.length > 0) {
|
|
3329
|
-
//throw new Error(`Validation errors: ${errors.join(', ')}`);
|
|
3330
|
-
errors.map((error) => {
|
|
3331
|
-
//console.log(error);
|
|
3332
|
-
throw error;
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
validateSequenceParents(parents, sequence_index, sequence) {
|
|
3337
|
-
const map = new Map();
|
|
3338
|
-
for (let i = 0; i < sequence_index; i++) {
|
|
3339
|
-
map.set(sequence[i].tag, i);
|
|
3340
|
-
}
|
|
3341
|
-
for (let i = 0; i < parents.length; i++) {
|
|
3342
|
-
if (map.get(parents[i]) === undefined) {
|
|
3343
|
-
throw new Error(`Invalid parent ${parents[i]} in sequence ${sequence[sequence_index].tag}, parents have to be declared before their children`);
|
|
3344
|
-
}
|
|
3345
|
-
}
|
|
3346
|
-
}
|
|
3347
3254
|
validateSequenceInputParents(parent, sequence_index, sequence) {
|
|
3348
3255
|
let found = false;
|
|
3349
3256
|
const parents = sequence[sequence_index].parents;
|
|
@@ -3356,112 +3263,6 @@ class ProductsBuilderService {
|
|
|
3356
3263
|
if (!found)
|
|
3357
3264
|
throw new Error(`Parents array needs to contain parent sequence ${parent} in ${sequence[sequence_index].tag}`);
|
|
3358
3265
|
}
|
|
3359
|
-
async checkAndValidateActionDataInput(data, sequence_index, event, event_index) {
|
|
3360
|
-
/*const application = this.fetchThirdPartyAppByAccessTag(event.a)
|
|
3361
|
-
|
|
3362
|
-
if (!application) {
|
|
3363
|
-
throw new Error(`App ${event.app} does not exist`);
|
|
3364
|
-
}
|
|
3365
|
-
|
|
3366
|
-
const { version, ...app } = application;
|
|
3367
|
-
const { access_tag } = app;*/
|
|
3368
|
-
// validate action_tag
|
|
3369
|
-
const app = await this.fetchThirdPartyAppByAccessTag(event.app);
|
|
3370
|
-
const { versions, version } = app;
|
|
3371
|
-
const versionExists = versions.find((data) => data.tag === version);
|
|
3372
|
-
if (!versionExists) {
|
|
3373
|
-
throw new Error(`Version ${version} does not exist on app ${event.app}`);
|
|
3374
|
-
}
|
|
3375
|
-
const { actions } = versionExists;
|
|
3376
|
-
const action = this.fetchThirdPartyAppActionByTag(actions, event.event);
|
|
3377
|
-
await this.validateActionDataInput(data, action, event.input, event_index, sequence_index);
|
|
3378
|
-
}
|
|
3379
|
-
async checkAndValidateFunctionDataInput(data, sequence_index, event, event_index) {
|
|
3380
|
-
const func = (await this.fetchFunction(event.event));
|
|
3381
|
-
await this.validateActionDataInput(data, func, event.input, event_index, sequence_index);
|
|
3382
|
-
}
|
|
3383
|
-
async checkAndValidateDBActionDataInput(data, sequence_index, event, event_index) {
|
|
3384
|
-
console.log('EVENTY', event.event);
|
|
3385
|
-
const { filterData, data: dbData, filterTemplate, template } = await this.fetchDatabaseAction(event.event);
|
|
3386
|
-
await this.validateDBActionDataInput(data, { filterData, data: dbData, template, filter: filterTemplate }, event.input, event_index, sequence_index);
|
|
3387
|
-
}
|
|
3388
|
-
async checkAndValidateFeatureDataInput(data, sequence_index, event, event_index) {
|
|
3389
|
-
const feature = await this.fetchFeature(event.event);
|
|
3390
|
-
if (!feature)
|
|
3391
|
-
throw new Error(`Feature ${event.event} not found`);
|
|
3392
|
-
const { input } = feature;
|
|
3393
|
-
await this.validateFeatureDataInput(data, input, event.input, event_index, sequence_index);
|
|
3394
|
-
}
|
|
3395
|
-
async checkAndValidateNotificationDataInput(data, sequence_index, event, event_index) {
|
|
3396
|
-
const { callback_data: callback, push_notification_data: notification, email_data: email, sms_data: sms, } = await this.fetchNotificationMessage(event.event);
|
|
3397
|
-
await this.validateNotificationDataInput(data, { callback, notification, email, sms }, event.input, event_index, sequence_index);
|
|
3398
|
-
}
|
|
3399
|
-
async checkAndValidatePublishDataInput(data, sequence_index, event, event_index) {
|
|
3400
|
-
const topic = await this.fetchMessageBrokerTopic(event.event);
|
|
3401
|
-
if (!topic) {
|
|
3402
|
-
throw new Error(`Topic ${event.event} not registered`);
|
|
3403
|
-
}
|
|
3404
|
-
const { data: topicData } = topic;
|
|
3405
|
-
//await this.validatePublishTopicDataInput(data, { data: topicData }, event.input, event_index, sequence_index)
|
|
3406
|
-
}
|
|
3407
|
-
async checkAndValidateStorageDataInput(data, sequence_index, event, event_index) {
|
|
3408
|
-
const storage = await this.fetchStorage(event.event);
|
|
3409
|
-
if (!storage) {
|
|
3410
|
-
throw new Error(`Storage ${event.event} does not exist`);
|
|
3411
|
-
}
|
|
3412
|
-
//await this.validateStorageDataInput(data, {}, event.input, event_index, sequence_index);
|
|
3413
|
-
}
|
|
3414
|
-
async checkAndValidateJobDataInput(data, sequence_index, event, event_index) {
|
|
3415
|
-
const job = await this.fetchJob(event.event);
|
|
3416
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.ACTION) {
|
|
3417
|
-
await this.checkAndValidateActionDataInput(data, sequence_index, event, event_index);
|
|
3418
|
-
}
|
|
3419
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.DATABASE_ACTION) {
|
|
3420
|
-
await this.checkAndValidateDBActionDataInput(data, sequence_index, event, event_index);
|
|
3421
|
-
}
|
|
3422
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.NOTIFICATION) {
|
|
3423
|
-
await this.checkAndValidateNotificationDataInput(data, sequence_index, event, event_index);
|
|
3424
|
-
}
|
|
3425
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.STORAGE) {
|
|
3426
|
-
await this.checkAndValidateStorageDataInput(data, sequence_index, event, event_index);
|
|
3427
|
-
}
|
|
3428
|
-
if (job.type === productsBuilder_types_1.JobEventTypes.PUBLISH) {
|
|
3429
|
-
await this.checkAndValidatePublishDataInput(data, sequence_index, event, event_index);
|
|
3430
|
-
}
|
|
3431
|
-
}
|
|
3432
|
-
async checkAndValidateFallbackDataInput(data, sequence_index, event, event_index) { }
|
|
3433
|
-
async validateEvent(data, sequence_index, event, event_index) {
|
|
3434
|
-
this.validateConditional(event, data, sequence_index, event_index);
|
|
3435
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.ACTION) {
|
|
3436
|
-
await this.checkAndValidateActionDataInput(data, sequence_index, event, event_index);
|
|
3437
|
-
// validate input
|
|
3438
|
-
}
|
|
3439
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.DB_ACTION) {
|
|
3440
|
-
await this.checkAndValidateDBActionDataInput(data, sequence_index, event, event_index);
|
|
3441
|
-
}
|
|
3442
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.FEATURE) {
|
|
3443
|
-
await this.checkAndValidateFeatureDataInput(data, sequence_index, event, event_index);
|
|
3444
|
-
}
|
|
3445
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.NOTIFICATION) {
|
|
3446
|
-
await this.checkAndValidateNotificationDataInput(data, sequence_index, event, event_index);
|
|
3447
|
-
}
|
|
3448
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.PUBLISH) {
|
|
3449
|
-
await this.checkAndValidatePublishDataInput(data, sequence_index, event, event_index);
|
|
3450
|
-
}
|
|
3451
|
-
/*if (event.type === FeatureEventTypes.SUBSCRIBE) {
|
|
3452
|
-
const topic = await this.fetchMessageBrokerTopic(event.event);
|
|
3453
|
-
|
|
3454
|
-
if(!topic) {
|
|
3455
|
-
throw new Error(`Topic ${event.event} not registered`);
|
|
3456
|
-
}
|
|
3457
|
-
}*/
|
|
3458
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.STORAGE) {
|
|
3459
|
-
await this.checkAndValidateStorageDataInput(data, sequence_index, event, event_index);
|
|
3460
|
-
}
|
|
3461
|
-
if (event.type === productsBuilder_types_1.FeatureEventTypes.JOB) {
|
|
3462
|
-
await this.checkAndValidateJobDataInput(data, sequence_index, event, event_index);
|
|
3463
|
-
}
|
|
3464
|
-
}
|
|
3465
3266
|
async validateDBActionDataInput(data, action, event_input, event_index, sequence_index) {
|
|
3466
3267
|
// const {data: dataInput, filter: filter} = event_input;
|
|
3467
3268
|
const indexes = {
|
|
@@ -3489,9 +3290,6 @@ class ProductsBuilderService {
|
|
|
3489
3290
|
indexes: indexes,
|
|
3490
3291
|
}, true);
|
|
3491
3292
|
}
|
|
3492
|
-
async validateFeatureDataInput(data, featureInput, input, event_index, sequence_index) {
|
|
3493
|
-
(0, processor_utils_1.validateFeatureJSONInput)(input, featureInput);
|
|
3494
|
-
}
|
|
3495
3293
|
async validateNotificationDataInput(data, action, event_input, event_index, sequence_index) {
|
|
3496
3294
|
// const {data: dataInput, filter: filter} = event_input;
|
|
3497
3295
|
const indexes = {
|
|
@@ -3738,93 +3536,6 @@ class ProductsBuilderService {
|
|
|
3738
3536
|
index++;
|
|
3739
3537
|
}
|
|
3740
3538
|
}
|
|
3741
|
-
validateConditional(event, feature, sequence_index, event_index) {
|
|
3742
|
-
const sequence = feature.sequence[sequence_index];
|
|
3743
|
-
const input = feature.input;
|
|
3744
|
-
const { condition } = event;
|
|
3745
|
-
// Define valid operators
|
|
3746
|
-
// Check if condition exists
|
|
3747
|
-
if (condition && condition.check) {
|
|
3748
|
-
// Split the check into parts: initiator, operator, and value
|
|
3749
|
-
const parts = (0, string_utils_1.extractConditionalParts)(condition.check);
|
|
3750
|
-
if (!parts) {
|
|
3751
|
-
throw new Error(`event ${event.event} in ${sequence.tag} has an invalid check format.
|
|
3752
|
-
Ensure it follows the pattern: initiator operator value (e.g., $Index < 10)
|
|
3753
|
-
Valid operators are: ${productsBuilder_types_1.ValidOperators.join(', ')}`);
|
|
3754
|
-
}
|
|
3755
|
-
const [, initiator, operator, value] = parts;
|
|
3756
|
-
if (condition.type === productsBuilder_types_1.Conditions.LOOP && initiator !== '$Index') {
|
|
3757
|
-
throw new Error(`invalid index ${initiator} in event ${event.event} in ${sequence.tag}, loop indexes are expected to be defined as $Index`);
|
|
3758
|
-
}
|
|
3759
|
-
// Validate operator
|
|
3760
|
-
if (!productsBuilder_types_1.ValidOperators.includes(operator)) {
|
|
3761
|
-
throw new Error(`event ${event.event} in ${sequence.tag} has an invalid operator "${operator}" for "${condition.type}" condition
|
|
3762
|
-
Valid operators are: ${productsBuilder_types_1.ValidOperators.join(', ')}`);
|
|
3763
|
-
}
|
|
3764
|
-
if (condition.type === productsBuilder_types_1.Conditions.LOOP && condition.iter) {
|
|
3765
|
-
// check if value is an integer
|
|
3766
|
-
throw new Error(`event ${event.event} in ${sequence.tag} has an invalid loop iter "${condition.iter}" is expected to be an integer .`);
|
|
3767
|
-
}
|
|
3768
|
-
// check if value is an integer
|
|
3769
|
-
if (condition.type === productsBuilder_types_1.Conditions.LOOP && condition.init && !Number.isInteger(condition.init)) {
|
|
3770
|
-
throw new Error(`event ${event.event} in ${sequence.tag} has an invalid loop init "${condition.init}" is expected to be an integer .`);
|
|
3771
|
-
}
|
|
3772
|
-
// check if value is not numeric but points towards a value
|
|
3773
|
-
if (condition.type === productsBuilder_types_1.Conditions.LOOP && !(0, string_utils_1.isNumeric)(value)) {
|
|
3774
|
-
//console.log(1, value);
|
|
3775
|
-
if (!value.startsWith('$')) {
|
|
3776
|
-
throw new Error(`event ${event.event} in ${sequence.tag} has an invalid operator "${operator}".`);
|
|
3777
|
-
}
|
|
3778
|
-
const payload = {
|
|
3779
|
-
datapoint: {
|
|
3780
|
-
key: 'condition-value',
|
|
3781
|
-
required: true,
|
|
3782
|
-
maxLength: 0,
|
|
3783
|
-
minLength: 0,
|
|
3784
|
-
type: enums_1.DataTypes.INTEGER, // value is expected to be a number
|
|
3785
|
-
},
|
|
3786
|
-
value,
|
|
3787
|
-
input: input,
|
|
3788
|
-
stages: this.extractStages(value),
|
|
3789
|
-
};
|
|
3790
|
-
const meta = { compare: true, feature, sequence_index, event_index, type: enums_1.Categories.CONDITIONAL };
|
|
3791
|
-
this.parseInputString(payload, meta);
|
|
3792
|
-
}
|
|
3793
|
-
if (condition.type === productsBuilder_types_1.Conditions.CHECK) {
|
|
3794
|
-
this.parseInputString({
|
|
3795
|
-
datapoint: {
|
|
3796
|
-
key: 'condition-initiator',
|
|
3797
|
-
required: true,
|
|
3798
|
-
maxLength: 0,
|
|
3799
|
-
minLength: 0,
|
|
3800
|
-
type: enums_1.DataTypes.STRING,
|
|
3801
|
-
},
|
|
3802
|
-
value: initiator,
|
|
3803
|
-
input: input,
|
|
3804
|
-
stages: this.extractStages(initiator),
|
|
3805
|
-
}, { compare: false, feature, sequence_index, event_index, type: enums_1.Categories.CONDITIONAL });
|
|
3806
|
-
//console.log(2, value);
|
|
3807
|
-
if (value.startsWith('$')) {
|
|
3808
|
-
this.parseInputString({
|
|
3809
|
-
datapoint: {
|
|
3810
|
-
key: 'condition-value',
|
|
3811
|
-
required: true,
|
|
3812
|
-
maxLength: 0,
|
|
3813
|
-
minLength: 0,
|
|
3814
|
-
type: enums_1.DataTypes.STRING,
|
|
3815
|
-
},
|
|
3816
|
-
value,
|
|
3817
|
-
input: input,
|
|
3818
|
-
stages: this.extractStages(value),
|
|
3819
|
-
}, { compare: false, feature, sequence_index, event_index, type: enums_1.Categories.CONDITIONAL });
|
|
3820
|
-
}
|
|
3821
|
-
}
|
|
3822
|
-
}
|
|
3823
|
-
// Check if the condition is a CHECK and allow_fail is true
|
|
3824
|
-
if (condition && condition.type === productsBuilder_types_1.Conditions.CHECK && event.allow_fail) {
|
|
3825
|
-
throw new Error(`event ${event.event} cannot set allow_fail: true as it is a check conditional`);
|
|
3826
|
-
}
|
|
3827
|
-
}
|
|
3828
3539
|
async parseActionEventInput(data) {
|
|
3829
3540
|
const datapoint = this.validateActionKeyPlacement(data);
|
|
3830
3541
|
let stages, input;
|
|
@@ -4028,7 +3739,7 @@ class ProductsBuilderService {
|
|
|
4028
3739
|
throw new Error(`event ${stage} not found in sequence ${sequence.tag}`);
|
|
4029
3740
|
}
|
|
4030
3741
|
let { type, app: access_tag, event: event_tag } = event;
|
|
4031
|
-
if (type === productsBuilder_types_1.
|
|
3742
|
+
if (type === productsBuilder_types_1.StepEventTypes.ACTION) {
|
|
4032
3743
|
const _b = await this.fetchThirdPartyAppByAccessTag(access_tag), { version } = _b, app = __rest(_b, ["version"]);
|
|
4033
3744
|
const { actions } = app.versions.find((data) => data.tag === version);
|
|
4034
3745
|
const { responses } = this.fetchThirdPartyAppActionByTag(actions, event_tag);
|
|
@@ -4038,13 +3749,13 @@ class ProductsBuilderService {
|
|
|
4038
3749
|
throw new Error(`event ${stage} does not have a success response`);
|
|
4039
3750
|
}
|
|
4040
3751
|
}
|
|
4041
|
-
if (type === productsBuilder_types_1.
|
|
3752
|
+
if (type === productsBuilder_types_1.StepEventTypes.DB_ACTION) {
|
|
4042
3753
|
// TODO:
|
|
4043
3754
|
}
|
|
4044
|
-
if (type === productsBuilder_types_1.
|
|
3755
|
+
if (type === productsBuilder_types_1.StepEventTypes.JOB) {
|
|
4045
3756
|
// TODO:
|
|
4046
3757
|
}
|
|
4047
|
-
if (type === productsBuilder_types_1.
|
|
3758
|
+
if (type === productsBuilder_types_1.StepEventTypes.NOTIFICATION) {
|
|
4048
3759
|
// TODO:
|
|
4049
3760
|
}
|
|
4050
3761
|
//TODO: handle other types
|
|
@@ -4312,70 +4023,6 @@ class ProductsBuilderService {
|
|
|
4312
4023
|
}
|
|
4313
4024
|
return action;
|
|
4314
4025
|
}
|
|
4315
|
-
async createFeature(data, throwErrorIfExists = false) {
|
|
4316
|
-
try {
|
|
4317
|
-
if (!(await this.fetchFeature(data.tag))) {
|
|
4318
|
-
await validators_1.CreateProductFeatureSchema.validateAsync(data);
|
|
4319
|
-
try {
|
|
4320
|
-
await this.validateFeatureData(data);
|
|
4321
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
4322
|
-
}
|
|
4323
|
-
catch (e) {
|
|
4324
|
-
throw e;
|
|
4325
|
-
}
|
|
4326
|
-
}
|
|
4327
|
-
else {
|
|
4328
|
-
if (throwErrorIfExists)
|
|
4329
|
-
throw new Error(`Feature ${data.tag} already exists`);
|
|
4330
|
-
}
|
|
4331
|
-
}
|
|
4332
|
-
catch (e) {
|
|
4333
|
-
throw e;
|
|
4334
|
-
}
|
|
4335
|
-
}
|
|
4336
|
-
async updateFeature(tag, data) {
|
|
4337
|
-
try {
|
|
4338
|
-
const feature = await this.fetchFeature(tag);
|
|
4339
|
-
if (!feature) {
|
|
4340
|
-
throw new Error(`Feature ${tag} not found`);
|
|
4341
|
-
}
|
|
4342
|
-
const { _id } = feature;
|
|
4343
|
-
await validators_1.UpdateProductFeatureSchema.validateAsync(data); // Change to update;
|
|
4344
|
-
await this.validateFeatureData(Object.assign({ tag }, data));
|
|
4345
|
-
if (data.tag && this.fetchFeature(data.tag)) {
|
|
4346
|
-
throw new Error(`tag ${tag} is in use`); // TODO: also check on the backend
|
|
4347
|
-
}
|
|
4348
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id,
|
|
4349
|
-
tag }, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
4350
|
-
}
|
|
4351
|
-
catch (e) {
|
|
4352
|
-
throw e;
|
|
4353
|
-
}
|
|
4354
|
-
}
|
|
4355
|
-
async fetchFeatures() {
|
|
4356
|
-
const components = await this.productApi.fetchProductComponents(this.product_id, 'feature', this.getUserAccess());
|
|
4357
|
-
return components;
|
|
4358
|
-
}
|
|
4359
|
-
async fetchFeature(tag) {
|
|
4360
|
-
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'feature', tag, this.getUserAccess());
|
|
4361
|
-
return component;
|
|
4362
|
-
}
|
|
4363
|
-
async deleteFeature(tag) {
|
|
4364
|
-
try {
|
|
4365
|
-
const feature = await this.fetchFeature(tag);
|
|
4366
|
-
if (!feature) {
|
|
4367
|
-
throw new Error(`Feature with tag: ${tag} not found`);
|
|
4368
|
-
}
|
|
4369
|
-
await this.productApi.updateProduct(this.product_id, {
|
|
4370
|
-
tag,
|
|
4371
|
-
component: enums_1.ProductComponents.FEATURE,
|
|
4372
|
-
action: enums_1.RequestAction.DELETE,
|
|
4373
|
-
}, this.getUserAccess());
|
|
4374
|
-
}
|
|
4375
|
-
catch (e) {
|
|
4376
|
-
throw e;
|
|
4377
|
-
}
|
|
4378
|
-
}
|
|
4379
4026
|
async createDatabase(data, throwErrorIfExists = false) {
|
|
4380
4027
|
try {
|
|
4381
4028
|
if (!(await this.fetchDatabase(data.tag))) {
|
|
@@ -5326,12 +4973,12 @@ class ProductsBuilderService {
|
|
|
5326
4973
|
}
|
|
5327
4974
|
}
|
|
5328
4975
|
// ==================== WORKFLOW CRUD METHODS ====================
|
|
5329
|
-
async
|
|
4976
|
+
async createFeature(data, throwErrorIfExists = false) {
|
|
5330
4977
|
try {
|
|
5331
|
-
if (!(await this.
|
|
4978
|
+
if (!(await this.fetchFeature(data.tag))) {
|
|
5332
4979
|
// Validate required fields
|
|
5333
4980
|
if (!data.name || !data.tag) {
|
|
5334
|
-
throw new Error('
|
|
4981
|
+
throw new Error('Feature requires name and tag');
|
|
5335
4982
|
}
|
|
5336
4983
|
// Validate envs if provided
|
|
5337
4984
|
if (data.envs && data.envs.length > 0) {
|
|
@@ -5342,25 +4989,25 @@ class ProductsBuilderService {
|
|
|
5342
4989
|
}
|
|
5343
4990
|
}
|
|
5344
4991
|
}
|
|
5345
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.
|
|
4992
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
5346
4993
|
}
|
|
5347
4994
|
else {
|
|
5348
4995
|
if (throwErrorIfExists)
|
|
5349
|
-
throw new Error(`
|
|
4996
|
+
throw new Error(`Feature already exists`);
|
|
5350
4997
|
}
|
|
5351
4998
|
}
|
|
5352
4999
|
catch (e) {
|
|
5353
5000
|
throw e;
|
|
5354
5001
|
}
|
|
5355
5002
|
}
|
|
5356
|
-
async
|
|
5003
|
+
async updateFeature(tag, data) {
|
|
5357
5004
|
try {
|
|
5358
|
-
const
|
|
5359
|
-
if (!
|
|
5360
|
-
throw new Error(`
|
|
5005
|
+
const feature = await this.fetchFeature(tag);
|
|
5006
|
+
if (!feature) {
|
|
5007
|
+
throw new Error(`Feature not found`);
|
|
5361
5008
|
}
|
|
5362
|
-
const { _id } =
|
|
5363
|
-
if (data.tag && data.tag !== tag && (await this.
|
|
5009
|
+
const { _id } = feature;
|
|
5010
|
+
if (data.tag && data.tag !== tag && (await this.fetchFeature(data.tag))) {
|
|
5364
5011
|
throw new Error(`tag ${data.tag} is in use`);
|
|
5365
5012
|
}
|
|
5366
5013
|
// Validate envs if provided
|
|
@@ -5372,29 +5019,29 @@ class ProductsBuilderService {
|
|
|
5372
5019
|
}
|
|
5373
5020
|
}
|
|
5374
5021
|
}
|
|
5375
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { tag, component: enums_1.ProductComponents.
|
|
5022
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({ _id }, data), { tag, component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
5376
5023
|
}
|
|
5377
5024
|
catch (e) {
|
|
5378
5025
|
throw e;
|
|
5379
5026
|
}
|
|
5380
5027
|
}
|
|
5381
|
-
async
|
|
5382
|
-
const components = await this.productApi.fetchProductComponents(this.product_id, '
|
|
5028
|
+
async fetchFeatures() {
|
|
5029
|
+
const components = await this.productApi.fetchProductComponents(this.product_id, 'feature', this.getUserAccess());
|
|
5383
5030
|
return components;
|
|
5384
5031
|
}
|
|
5385
|
-
async
|
|
5386
|
-
const component = await this.productApi.fetchProductComponentByTag(this.product_id, '
|
|
5032
|
+
async fetchFeature(tag) {
|
|
5033
|
+
const component = await this.productApi.fetchProductComponentByTag(this.product_id, 'feature', tag, this.getUserAccess());
|
|
5387
5034
|
return component;
|
|
5388
5035
|
}
|
|
5389
|
-
async
|
|
5036
|
+
async deleteFeature(tag) {
|
|
5390
5037
|
try {
|
|
5391
|
-
const
|
|
5392
|
-
if (!
|
|
5393
|
-
throw new Error(`
|
|
5038
|
+
const feature = await this.fetchFeature(tag);
|
|
5039
|
+
if (!feature) {
|
|
5040
|
+
throw new Error(`Feature with tag: not found`);
|
|
5394
5041
|
}
|
|
5395
5042
|
await this.productApi.updateProduct(this.product_id, {
|
|
5396
5043
|
tag,
|
|
5397
|
-
component: enums_1.ProductComponents.
|
|
5044
|
+
component: enums_1.ProductComponents.FEATURE,
|
|
5398
5045
|
action: enums_1.RequestAction.DELETE,
|
|
5399
5046
|
}, this.getUserAccess());
|
|
5400
5047
|
}
|
|
@@ -6179,7 +5826,7 @@ class ProductsBuilderService {
|
|
|
6179
5826
|
}
|
|
6180
5827
|
}
|
|
6181
5828
|
}
|
|
6182
|
-
/** Only log when DUCTAPE_DEBUG is set (avoids sync I/O cost in
|
|
5829
|
+
/** Only log when DUCTAPE_DEBUG is set (avoids sync I/O cost in feature hot path) */
|
|
6183
5830
|
ProductsBuilderService._debug = typeof process !== 'undefined' && (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DUCTAPE_DEBUG) === 'true' || ((_b = process.env) === null || _b === void 0 ? void 0 : _b.DUCTAPE_DEBUG) === '1');
|
|
6184
5831
|
exports.default = ProductsBuilderService;
|
|
6185
5832
|
//# sourceMappingURL=products.service.js.map
|