@ductape/sdk 0.1.20 → 0.1.22
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/agents/agents.service.d.ts +2 -0
- package/dist/agents/agents.service.js +26 -3
- package/dist/agents/agents.service.js.map +1 -1
- package/dist/api/services/logsApi.service.js +5 -1
- package/dist/api/services/logsApi.service.js.map +1 -1
- package/dist/api/services/productsApi.service.d.ts +111 -0
- package/dist/api/services/productsApi.service.js +90 -0
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/api/urls.d.ts +7 -0
- package/dist/api/urls.js +14 -7
- package/dist/api/urls.js.map +1 -1
- package/dist/apps/services/app.service.js +7 -2
- package/dist/apps/services/app.service.js.map +1 -1
- package/dist/brokers/brokers.service.js +20 -12
- package/dist/brokers/brokers.service.js.map +1 -1
- package/dist/database/adapters/mysql.adapter.js +8 -3
- package/dist/database/adapters/mysql.adapter.js.map +1 -1
- package/dist/database/adapters/postgresql.adapter.js +6 -2
- package/dist/database/adapters/postgresql.adapter.js.map +1 -1
- package/dist/database/databases.service.d.ts +10 -1
- package/dist/database/databases.service.js +84 -27
- package/dist/database/databases.service.js.map +1 -1
- package/dist/graph/graphs.service.d.ts +7 -3
- package/dist/graph/graphs.service.js +67 -31
- package/dist/graph/graphs.service.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.js +32 -93
- package/dist/index.js.map +1 -1
- package/dist/logs/logs.service.d.ts +3 -1
- package/dist/logs/logs.service.js +12 -2
- package/dist/logs/logs.service.js.map +1 -1
- package/dist/logs/logs.types.d.ts +4 -0
- package/dist/logs/logs.types.js.map +1 -1
- package/dist/notifications/notifications.service.d.ts +6 -0
- package/dist/notifications/notifications.service.js +54 -17
- package/dist/notifications/notifications.service.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +0 -14
- package/dist/processor/services/processor.service.js +6 -72
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/products/bootstrap-cache.d.ts +22 -0
- package/dist/products/bootstrap-cache.js +78 -0
- package/dist/products/bootstrap-cache.js.map +1 -0
- package/dist/products/services/products.service.d.ts +46 -3
- package/dist/products/services/products.service.js +304 -125
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productFallback.validator.js +1 -1
- package/dist/products/validators/joi-validators/create.productGraph.validator.js +7 -0
- package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productQuota.validator.js +1 -1
- package/dist/products/validators/joi-validators/create.productVector.validator.js +6 -0
- package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productFallback.validator.js +1 -1
- package/dist/products/validators/joi-validators/update.productGraph.validator.js +9 -0
- package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -1
- package/dist/products/validators/joi-validators/update.productQuota.validator.js +1 -1
- package/dist/resilience/fallback.service.d.ts +3 -0
- package/dist/resilience/fallback.service.js +49 -14
- package/dist/resilience/fallback.service.js.map +1 -1
- package/dist/resilience/healthcheck.service.d.ts +3 -0
- package/dist/resilience/healthcheck.service.js +57 -7
- package/dist/resilience/healthcheck.service.js.map +1 -1
- package/dist/resilience/quota.service.d.ts +3 -0
- package/dist/resilience/quota.service.js +49 -14
- package/dist/resilience/quota.service.js.map +1 -1
- package/dist/resilience/resilience-execution.utils.d.ts +22 -0
- package/dist/resilience/resilience-execution.utils.js +81 -0
- package/dist/resilience/resilience-execution.utils.js.map +1 -0
- package/dist/sessions/sessions.service.d.ts +9 -1
- package/dist/sessions/sessions.service.js +125 -49
- package/dist/sessions/sessions.service.js.map +1 -1
- package/dist/types/index.types.d.ts +8 -0
- package/dist/types/index.types.js.map +1 -1
- package/dist/types/processor.types.d.ts +3 -0
- package/dist/types/processor.types.js.map +1 -1
- package/dist/types/requests.types.d.ts +4 -0
- package/dist/vector/vector-database.service.d.ts +6 -0
- package/dist/vector/vector-database.service.js +66 -8
- package/dist/vector/vector-database.service.js.map +1 -1
- package/package.json +3 -1
|
@@ -32,6 +32,7 @@ const productsBuilder_types_1 = require("../../types/productsBuilder.types");
|
|
|
32
32
|
const validators_1 = require("../validators");
|
|
33
33
|
const objects_utils_1 = require("../utils/objects.utils");
|
|
34
34
|
const processor_utils_1 = require("../../processor/utils/processor.utils");
|
|
35
|
+
const bootstrap_cache_1 = require("../bootstrap-cache");
|
|
35
36
|
const create_productDatabaseAction_validator_1 = require("../validators/joi-validators/create.productDatabaseAction.validator");
|
|
36
37
|
const update_productDatabaseAction_validator_1 = require("../validators/joi-validators/update.productDatabaseAction.validator");
|
|
37
38
|
const create_productStorage_validator_1 = require("../validators/joi-validators/create.productStorage.validator");
|
|
@@ -82,6 +83,34 @@ class ProductsBuilderService {
|
|
|
82
83
|
if (queues) {
|
|
83
84
|
this.queues = queues;
|
|
84
85
|
}
|
|
86
|
+
this.bootstrapCache = new bootstrap_cache_1.BootstrapCache(this.workspace_id, this.redisClient, this.workspace_private_key);
|
|
87
|
+
}
|
|
88
|
+
applyBootstrapProductContext(productTag, boot) {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
if (boot.product_id) {
|
|
91
|
+
this.product_id = boot.product_id;
|
|
92
|
+
}
|
|
93
|
+
const hasPrivateKey = boot.private_key != null && String(boot.private_key).trim() !== '';
|
|
94
|
+
if (hasPrivateKey) {
|
|
95
|
+
this.product = {
|
|
96
|
+
_id: boot.product_id,
|
|
97
|
+
workspace_id: boot.workspace_id,
|
|
98
|
+
private_key: boot.private_key,
|
|
99
|
+
tag: productTag !== null && productTag !== void 0 ? productTag : ((_b = (_a = this.product) === null || _a === void 0 ? void 0 : _a.tag) !== null && _b !== void 0 ? _b : ''),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async cachedBootstrap(domain, keyParts, fetch, apply) {
|
|
104
|
+
const key = (0, bootstrap_cache_1.buildBootstrapCacheKey)(domain, this.workspace_id, keyParts);
|
|
105
|
+
const cached = await this.bootstrapCache.get(key);
|
|
106
|
+
if (cached) {
|
|
107
|
+
apply === null || apply === void 0 ? void 0 : apply(cached);
|
|
108
|
+
return cached;
|
|
109
|
+
}
|
|
110
|
+
const result = await fetch();
|
|
111
|
+
apply === null || apply === void 0 ? void 0 : apply(result);
|
|
112
|
+
this.bootstrapCache.set(key, result);
|
|
113
|
+
return result;
|
|
85
114
|
}
|
|
86
115
|
fetchPrivateKey() {
|
|
87
116
|
var _a;
|
|
@@ -236,6 +265,32 @@ class ProductsBuilderService {
|
|
|
236
265
|
option.check_interval = 10000;
|
|
237
266
|
}
|
|
238
267
|
}
|
|
268
|
+
/** Validate a quota/fallback action provider (app action or product workflow). */
|
|
269
|
+
async validateQuotaFallbackProvider(option) {
|
|
270
|
+
var _a;
|
|
271
|
+
if (option.type !== productsBuilder_types_1.FeatureEventTypes.ACTION)
|
|
272
|
+
return;
|
|
273
|
+
if ((_a = option.app) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
274
|
+
const app = await this.fetchThirdPartyAppByAccessTag(option.app);
|
|
275
|
+
if (!app) {
|
|
276
|
+
throw new Error(`App with access tag ${option.app} not found`);
|
|
277
|
+
}
|
|
278
|
+
const version = app.versions.find((v) => v.tag === app.version);
|
|
279
|
+
const action = version === null || version === void 0 ? void 0 : version.actions.find((a) => a.tag === option.event);
|
|
280
|
+
if (!action) {
|
|
281
|
+
throw new Error(`Cannot find action ${option.event} on app ${app.tag} version ${app.version}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
const workflow = await this.fetchWorkflow(option.event);
|
|
286
|
+
if (!workflow) {
|
|
287
|
+
throw new Error(`Workflow ${option.event} not found on product`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (option.healthcheck) {
|
|
291
|
+
await this.validateProviderHealthcheckTag(option);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
239
294
|
/** Keep in-memory product component arrays in sync after component CRUD (components API can lag). */
|
|
240
295
|
mergeProductComponent(kind, item) {
|
|
241
296
|
if (!this.product || !(item === null || item === void 0 ? void 0 : item.tag))
|
|
@@ -278,6 +333,27 @@ class ProductsBuilderService {
|
|
|
278
333
|
event,
|
|
279
334
|
envs, action: enums_1.RequestAction.CREATE, component: enums_1.ProductComponents.HEALTHCHECK }), this.getUserAccess());
|
|
280
335
|
}
|
|
336
|
+
async updateHealthcheckFromSchema(schema) {
|
|
337
|
+
var _a, _b, _c;
|
|
338
|
+
const probe = schema.probe;
|
|
339
|
+
const probeInput = (probe === null || probe === void 0 ? void 0 : probe.input) != null ? probe.input : undefined;
|
|
340
|
+
const app = (_a = probe === null || probe === void 0 ? void 0 : probe.app) !== null && _a !== void 0 ? _a : schema.app;
|
|
341
|
+
const event = (_b = probe === null || probe === void 0 ? void 0 : probe.event) !== null && _b !== void 0 ? _b : schema.event;
|
|
342
|
+
if (probeInput != null && !((_c = this.product) === null || _c === void 0 ? void 0 : _c.private_key)) {
|
|
343
|
+
throw new Error('Healthcheck inputs must be encrypted with the product private key; product not initialized or missing private_key');
|
|
344
|
+
}
|
|
345
|
+
const envs = await Promise.all((schema.envs || []).map(async (env) => {
|
|
346
|
+
var _a;
|
|
347
|
+
const input = env.input != null ? env.input : probeInput;
|
|
348
|
+
const encrypted = input != null && ((_a = this.product) === null || _a === void 0 ? void 0 : _a.private_key)
|
|
349
|
+
? (0, processor_utils_1.encrypt)(JSON.stringify(input), this.product.private_key)
|
|
350
|
+
: input;
|
|
351
|
+
return Object.assign(Object.assign({}, env), { input: encrypted });
|
|
352
|
+
}));
|
|
353
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, schema), { app,
|
|
354
|
+
event,
|
|
355
|
+
envs, action: enums_1.RequestAction.UPDATE, component: enums_1.ProductComponents.HEALTHCHECK }), this.getUserAccess());
|
|
356
|
+
}
|
|
281
357
|
async updateDataValidation(selector, update) {
|
|
282
358
|
if (!selector.startsWith('$Data{') && !selector.startsWith('$Filter')) {
|
|
283
359
|
throw new Error(`selector ${selector} is expected to start with $Data or $Filter`);
|
|
@@ -416,22 +492,9 @@ class ProductsBuilderService {
|
|
|
416
492
|
* Returns only the minimal action data needed to execute
|
|
417
493
|
*/
|
|
418
494
|
async bootstrapAction(params) {
|
|
495
|
+
var _a;
|
|
419
496
|
try {
|
|
420
|
-
|
|
421
|
-
// Initialize minimal product data so fetchPrivateKey/fetchProductId/fetchWorkspaceId work
|
|
422
|
-
if (result.product_id) {
|
|
423
|
-
this.product_id = result.product_id;
|
|
424
|
-
}
|
|
425
|
-
const hasPrivateKey = result.private_key != null && String(result.private_key).trim() !== '';
|
|
426
|
-
if (hasPrivateKey) {
|
|
427
|
-
this.product = {
|
|
428
|
-
_id: result.product_id,
|
|
429
|
-
workspace_id: result.workspace_id,
|
|
430
|
-
private_key: result.private_key,
|
|
431
|
-
tag: params.product_tag,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
return result;
|
|
497
|
+
return await this.cachedBootstrap('action', [(_a = params.product_tag) !== null && _a !== void 0 ? _a : '', params.access_tag, params.env_slug, params.action_tag], () => this.productApi.bootstrapAction(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
435
498
|
}
|
|
436
499
|
catch (e) {
|
|
437
500
|
throw e;
|
|
@@ -458,14 +521,17 @@ class ProductsBuilderService {
|
|
|
458
521
|
}
|
|
459
522
|
async bootstrapNotification(params) {
|
|
460
523
|
try {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
|
|
524
|
+
return await this.cachedBootstrap('notification', [params.product_tag, params.env_slug, params.notification_tag, params.message_tag], async () => {
|
|
525
|
+
const result = await this.productApi.bootstrapNotification(params, this.getUserAccess());
|
|
526
|
+
if (result.notification && result.private_key) {
|
|
527
|
+
result.notification = this.decryptNotificationChannelConfigs(result.notification, result.private_key);
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}, (result) => {
|
|
531
|
+
if (result.product_id) {
|
|
532
|
+
this.product_id = result.product_id;
|
|
533
|
+
}
|
|
534
|
+
});
|
|
469
535
|
}
|
|
470
536
|
catch (e) {
|
|
471
537
|
throw e;
|
|
@@ -473,11 +539,68 @@ class ProductsBuilderService {
|
|
|
473
539
|
}
|
|
474
540
|
async bootstrapStorage(params) {
|
|
475
541
|
try {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
542
|
+
return await this.cachedBootstrap('storage', [params.product_tag, params.env_slug, params.storage_tag], () => this.productApi.bootstrapStorage(params, this.getUserAccess()), (result) => {
|
|
543
|
+
if (result.product_id) {
|
|
544
|
+
this.product_id = result.product_id;
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
throw e;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async bootstrapSession(params) {
|
|
553
|
+
try {
|
|
554
|
+
return await this.cachedBootstrap('session', [params.product_tag, params.env_slug, params.session_tag], () => this.productApi.bootstrapSession(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
555
|
+
}
|
|
556
|
+
catch (e) {
|
|
557
|
+
throw e;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async bootstrapDatabase(params) {
|
|
561
|
+
try {
|
|
562
|
+
return await this.cachedBootstrap('database', [params.product_tag, params.env_slug, params.database_tag], () => this.productApi.bootstrapDatabase(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
563
|
+
}
|
|
564
|
+
catch (e) {
|
|
565
|
+
throw e;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
async bootstrapBroker(params) {
|
|
569
|
+
var _a;
|
|
570
|
+
try {
|
|
571
|
+
return await this.cachedBootstrap('broker', [params.product_tag, params.env_slug, params.broker_tag, (_a = params.topic_tag) !== null && _a !== void 0 ? _a : ''], () => this.productApi.bootstrapBroker(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
572
|
+
}
|
|
573
|
+
catch (e) {
|
|
574
|
+
throw e;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
async bootstrapGraph(params) {
|
|
578
|
+
try {
|
|
579
|
+
return await this.cachedBootstrap('graph', [params.product_tag, params.env_slug, params.graph_tag], () => this.productApi.bootstrapGraph(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
580
|
+
}
|
|
581
|
+
catch (e) {
|
|
582
|
+
throw e;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async bootstrapVector(params) {
|
|
586
|
+
try {
|
|
587
|
+
return await this.cachedBootstrap('vector', [params.product_tag, params.env_slug, params.vector_tag], () => this.productApi.bootstrapVector(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
588
|
+
}
|
|
589
|
+
catch (e) {
|
|
590
|
+
throw e;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
async bootstrapResilience(params) {
|
|
594
|
+
try {
|
|
595
|
+
return await this.cachedBootstrap('resilience', [params.product_tag, params.env_slug, params.component_type, params.component_tag], () => this.productApi.bootstrapResilience(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
596
|
+
}
|
|
597
|
+
catch (e) {
|
|
598
|
+
throw e;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async bootstrapIntelligence(params) {
|
|
602
|
+
try {
|
|
603
|
+
return await this.cachedBootstrap('intelligence', [params.product_tag, params.env_slug, params.agent_tag], () => this.productApi.bootstrapIntelligence(params, this.getUserAccess()), (result) => this.applyBootstrapProductContext(params.product_tag, result));
|
|
481
604
|
}
|
|
482
605
|
catch (e) {
|
|
483
606
|
throw e;
|
|
@@ -489,19 +612,21 @@ class ProductsBuilderService {
|
|
|
489
612
|
async bootstrapWorkflow(params) {
|
|
490
613
|
try {
|
|
491
614
|
const auth = this.getUserAccess();
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
615
|
+
return await this.cachedBootstrap('workflow', [params.product_tag, params.env_slug, (0, bootstrap_cache_1.hashWorkflowSteps)(params.steps)], async () => {
|
|
616
|
+
const result = await this.productApi.bootstrapWorkflow(Object.assign(Object.assign({}, params), { workspace_id: auth.workspace_id }), auth);
|
|
617
|
+
if (result && typeof result === 'object') {
|
|
618
|
+
for (const stepTag of Object.keys(result)) {
|
|
619
|
+
const data = result[stepTag];
|
|
620
|
+
if (data === null || data === void 0 ? void 0 : data.product_id) {
|
|
621
|
+
this.product_id = data.product_id;
|
|
622
|
+
}
|
|
623
|
+
if ((data === null || data === void 0 ? void 0 : data.notification) && (data === null || data === void 0 ? void 0 : data.private_key)) {
|
|
624
|
+
result[stepTag] = Object.assign(Object.assign({}, data), { notification: this.decryptNotificationChannelConfigs(data.notification, data.private_key) });
|
|
625
|
+
}
|
|
501
626
|
}
|
|
502
627
|
}
|
|
503
|
-
|
|
504
|
-
|
|
628
|
+
return result !== null && result !== void 0 ? result : {};
|
|
629
|
+
});
|
|
505
630
|
}
|
|
506
631
|
catch (e) {
|
|
507
632
|
throw e;
|
|
@@ -1070,20 +1195,7 @@ class ProductsBuilderService {
|
|
|
1070
1195
|
data.total_init = 0;
|
|
1071
1196
|
await Promise.all(data.options.map(async (d) => {
|
|
1072
1197
|
data.total_quota += d.quota;
|
|
1073
|
-
|
|
1074
|
-
const app = await this.fetchThirdPartyAppByAccessTag(d.app);
|
|
1075
|
-
if (!app) {
|
|
1076
|
-
throw new Error(`App with access tag ${d.app} not found`);
|
|
1077
|
-
}
|
|
1078
|
-
const version = app.versions.find((version) => version.tag === app.version);
|
|
1079
|
-
const action = version.actions.find((action) => action.tag === d.event);
|
|
1080
|
-
if (!action) {
|
|
1081
|
-
throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
|
|
1082
|
-
}
|
|
1083
|
-
if (d.healthcheck) {
|
|
1084
|
-
await this.validateProviderHealthcheckTag(d);
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1198
|
+
await this.validateQuotaFallbackProvider(d);
|
|
1087
1199
|
d.last_checked = new Date();
|
|
1088
1200
|
d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
|
|
1089
1201
|
d.last_available = true;
|
|
@@ -1108,20 +1220,7 @@ class ProductsBuilderService {
|
|
|
1108
1220
|
data.tag = tag;
|
|
1109
1221
|
await Promise.all(data.options.map(async (d) => {
|
|
1110
1222
|
data.total_quota += d.quota;
|
|
1111
|
-
|
|
1112
|
-
const app = await this.fetchThirdPartyAppByAccessTag(d.app);
|
|
1113
|
-
if (!app) {
|
|
1114
|
-
throw new Error(`App with access tag ${d.app} not found`);
|
|
1115
|
-
}
|
|
1116
|
-
const version = app.versions.find((version) => version.tag === app.version);
|
|
1117
|
-
const action = version.actions.find((action) => action.tag === d.event);
|
|
1118
|
-
if (!action) {
|
|
1119
|
-
throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
|
|
1120
|
-
}
|
|
1121
|
-
if (d.healthcheck) {
|
|
1122
|
-
await this.validateProviderHealthcheckTag(d);
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1223
|
+
await this.validateQuotaFallbackProvider(d);
|
|
1125
1224
|
d.last_checked = new Date();
|
|
1126
1225
|
d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
|
|
1127
1226
|
d.last_available = true;
|
|
@@ -1177,20 +1276,7 @@ class ProductsBuilderService {
|
|
|
1177
1276
|
await validators_1.CreateProductFallbackSchema.validateAsync(data);
|
|
1178
1277
|
await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
|
|
1179
1278
|
await Promise.all(data.options.map(async (d) => {
|
|
1180
|
-
|
|
1181
|
-
const app = await this.fetchThirdPartyAppByAccessTag(d.app);
|
|
1182
|
-
if (!app) {
|
|
1183
|
-
throw new Error(`App with access tag ${d.app} not found`);
|
|
1184
|
-
}
|
|
1185
|
-
const version = app.versions.find((version) => version.tag === app.version);
|
|
1186
|
-
const action = version.actions.find((action) => action.tag === d.event);
|
|
1187
|
-
if (!action) {
|
|
1188
|
-
throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
|
|
1189
|
-
}
|
|
1190
|
-
if (d.healthcheck) {
|
|
1191
|
-
await this.validateProviderHealthcheckTag(d);
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1279
|
+
await this.validateQuotaFallbackProvider(d);
|
|
1194
1280
|
d.last_checked = new Date();
|
|
1195
1281
|
d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
|
|
1196
1282
|
d.last_available = true;
|
|
@@ -1212,20 +1298,7 @@ class ProductsBuilderService {
|
|
|
1212
1298
|
await this.validateQuotaFallbackInputAndOutput(data, 'fallback');
|
|
1213
1299
|
data.tag = tag;
|
|
1214
1300
|
await Promise.all(data.options.map(async (d) => {
|
|
1215
|
-
|
|
1216
|
-
const app = await this.fetchThirdPartyAppByAccessTag(d.app);
|
|
1217
|
-
if (!app) {
|
|
1218
|
-
throw new Error(`App with access tag ${d.app} not found`);
|
|
1219
|
-
}
|
|
1220
|
-
const version = app.versions.find((version) => version.tag === app.version);
|
|
1221
|
-
const action = version.actions.find((action) => action.tag === d.event);
|
|
1222
|
-
if (!action) {
|
|
1223
|
-
throw new Error(`Cannot find action ${d.event} on app ${app.tag} version ${app.version}`);
|
|
1224
|
-
}
|
|
1225
|
-
if (d.healthcheck) {
|
|
1226
|
-
await this.validateProviderHealthcheckTag(d);
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1301
|
+
await this.validateQuotaFallbackProvider(d);
|
|
1229
1302
|
d.last_checked = new Date();
|
|
1230
1303
|
d.provider_status = productsBuilder_types_1.ProviderStatus.AVAILABLE;
|
|
1231
1304
|
d.last_available = true;
|
|
@@ -2403,9 +2476,13 @@ class ProductsBuilderService {
|
|
|
2403
2476
|
}
|
|
2404
2477
|
async validateAppData(appData, app) {
|
|
2405
2478
|
// TODO:
|
|
2479
|
+
var _a;
|
|
2406
2480
|
const { envs } = app;
|
|
2407
2481
|
// const { envs: appEnvs, auths: appAuths } = appData
|
|
2408
|
-
const version = appData.versions.find((data) =>
|
|
2482
|
+
const version = (_a = appData.versions.find((data) => data.latest === true)) !== null && _a !== void 0 ? _a : appData.versions[0];
|
|
2483
|
+
if (!version) {
|
|
2484
|
+
throw new Error(`App ${appData.tag} has no versions`);
|
|
2485
|
+
}
|
|
2409
2486
|
app.envs = this.validateAppEnvs(envs, version);
|
|
2410
2487
|
// await this.validateAppAuth(auth, appData);
|
|
2411
2488
|
return app;
|
|
@@ -2538,31 +2615,114 @@ class ProductsBuilderService {
|
|
|
2538
2615
|
}
|
|
2539
2616
|
return { data: updateData, values: updateValues };
|
|
2540
2617
|
}
|
|
2541
|
-
async createAppAccessTag(app_tag) {
|
|
2618
|
+
async createAppAccessTag(app_tag, known_app_id) {
|
|
2542
2619
|
await this.initializeWorkspace();
|
|
2543
2620
|
const { name: workspace_name } = this.workspace;
|
|
2544
|
-
|
|
2545
|
-
if (!
|
|
2546
|
-
|
|
2621
|
+
let app_id = known_app_id === null || known_app_id === void 0 ? void 0 : known_app_id.trim();
|
|
2622
|
+
if (!app_id) {
|
|
2623
|
+
const app = await this.appApi.fetchAppByTag(app_tag, this.getUserAccess());
|
|
2624
|
+
if (!app) {
|
|
2625
|
+
throw new Error(`App ${app_tag} not found`);
|
|
2626
|
+
}
|
|
2627
|
+
app_id = String(app._id);
|
|
2547
2628
|
}
|
|
2548
|
-
const { _id: app_id } = app;
|
|
2549
2629
|
const accessTag = `${app_tag}:${(0, string_utils_2.tagify)(workspace_name)}`;
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
access_tag
|
|
2553
|
-
|
|
2554
|
-
|
|
2630
|
+
try {
|
|
2631
|
+
const existing = await this.appApi.fetchAccessByTag(accessTag, this.getUserAccess());
|
|
2632
|
+
if ((existing === null || existing === void 0 ? void 0 : existing.access_tag) && (await this.accessAppIsLive(existing))) {
|
|
2633
|
+
return {
|
|
2634
|
+
access_tag: existing.access_tag,
|
|
2635
|
+
access: existing.access,
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
catch (_a) {
|
|
2640
|
+
// no existing access row — create below
|
|
2641
|
+
}
|
|
2642
|
+
try {
|
|
2643
|
+
const { access, access_tag } = await this.appApi.createAppAccess(app_id, this.product_id, accessTag, this.getUserAccess());
|
|
2644
|
+
return {
|
|
2645
|
+
access_tag,
|
|
2646
|
+
access,
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2649
|
+
catch (e) {
|
|
2650
|
+
try {
|
|
2651
|
+
const existing = await this.appApi.fetchAccessByTag(accessTag, this.getUserAccess());
|
|
2652
|
+
if ((existing === null || existing === void 0 ? void 0 : existing.access_tag) && (await this.accessAppIsLive(existing))) {
|
|
2653
|
+
return {
|
|
2654
|
+
access_tag: existing.access_tag,
|
|
2655
|
+
access: existing.access,
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
catch (_b) {
|
|
2660
|
+
// fall through to original error
|
|
2661
|
+
}
|
|
2662
|
+
throw e;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
async accessAppIsLive(access) {
|
|
2666
|
+
const appId = (access === null || access === void 0 ? void 0 : access.app_id) == null ? '' : String(access.app_id).trim();
|
|
2667
|
+
if (!appId)
|
|
2668
|
+
return false;
|
|
2669
|
+
try {
|
|
2670
|
+
const appData = await this.appApi.fetchApp(appId, this.getUserAccess());
|
|
2671
|
+
return appData != null;
|
|
2672
|
+
}
|
|
2673
|
+
catch (_a) {
|
|
2674
|
+
return false;
|
|
2675
|
+
}
|
|
2555
2676
|
}
|
|
2556
2677
|
async addApp(app, throwErrorIfExists = false) {
|
|
2678
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2557
2679
|
try {
|
|
2558
2680
|
await validators_1.CreateProductAppSchema.validateAsync(app);
|
|
2559
2681
|
// TODO: figure out a way to check if this has run before, halt if it has
|
|
2560
2682
|
if (!await this.fetchApp(app.access_tag, throwErrorIfExists)) {
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2683
|
+
let access = null;
|
|
2684
|
+
try {
|
|
2685
|
+
const fetched = await this.appApi.fetchAccessByTag(app.access_tag, this.getUserAccess());
|
|
2686
|
+
access = fetched ? Object.assign({}, fetched) : null;
|
|
2687
|
+
}
|
|
2688
|
+
catch (_g) {
|
|
2689
|
+
access = null;
|
|
2690
|
+
}
|
|
2691
|
+
if (access === null || access === void 0 ? void 0 : access.app_id) {
|
|
2692
|
+
const liveApp = await this.appApi.fetchApp(access.app_id, this.getUserAccess());
|
|
2693
|
+
if (!liveApp) {
|
|
2694
|
+
access = null;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
if (!(access === null || access === void 0 ? void 0 : access.app_id)) {
|
|
2698
|
+
const wsSuffix = `:${(0, string_utils_2.tagify)(this.workspace.name)}`;
|
|
2699
|
+
const appTag = app.access_tag.endsWith(wsSuffix)
|
|
2700
|
+
? app.access_tag.slice(0, -wsSuffix.length)
|
|
2701
|
+
: '';
|
|
2702
|
+
if (!appTag) {
|
|
2703
|
+
throw new Error(`Access to app ${app.access_tag} not found`);
|
|
2704
|
+
}
|
|
2705
|
+
const appRow = await this.appApi.fetchAppByTag(appTag, this.getUserAccess());
|
|
2706
|
+
if (!(appRow === null || appRow === void 0 ? void 0 : appRow._id)) {
|
|
2707
|
+
throw new Error(`App not found for tag ${appTag}`);
|
|
2708
|
+
}
|
|
2709
|
+
const created = await this.appApi.createAppAccess(String(appRow._id), this.product_id, app.access_tag, this.getUserAccess());
|
|
2710
|
+
const auth = this.getUserAccess();
|
|
2711
|
+
const latestVersion = (_f = (_c = (_b = (_a = appRow.versions) === null || _a === void 0 ? void 0 : _a.find((v) => v.latest)) === null || _b === void 0 ? void 0 : _b.tag) !== null && _c !== void 0 ? _c : (_e = (_d = appRow.versions) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.tag) !== null && _f !== void 0 ? _f : '';
|
|
2712
|
+
access = {
|
|
2713
|
+
workspace_id: auth.workspace_id,
|
|
2714
|
+
user_id: auth.user_id,
|
|
2715
|
+
public_key: auth.public_key,
|
|
2716
|
+
token: auth.token,
|
|
2717
|
+
product_id: this.product_id,
|
|
2718
|
+
app_id: String(appRow._id),
|
|
2719
|
+
access_tag: created.access_tag,
|
|
2720
|
+
access: created.access,
|
|
2721
|
+
version: latestVersion,
|
|
2722
|
+
};
|
|
2564
2723
|
}
|
|
2565
|
-
const
|
|
2724
|
+
const _h = access, { version } = _h, accessFields = __rest(_h, ["version"]);
|
|
2725
|
+
const appData = await this.appApi.fetchApp(accessFields.app_id, this.getUserAccess());
|
|
2566
2726
|
if (!appData) {
|
|
2567
2727
|
throw new Error(`App ${app.access_tag} not found`);
|
|
2568
2728
|
}
|
|
@@ -4347,6 +4507,24 @@ class ProductsBuilderService {
|
|
|
4347
4507
|
}
|
|
4348
4508
|
return component;
|
|
4349
4509
|
}
|
|
4510
|
+
/** Resolve database config from in-memory product cache, falling back to API fetch. */
|
|
4511
|
+
async resolveDatabaseConfig(databaseTag) {
|
|
4512
|
+
var _a;
|
|
4513
|
+
const cached = ((_a = this.product.databases) !== null && _a !== void 0 ? _a : []).find((data) => data.tag === databaseTag);
|
|
4514
|
+
if (cached)
|
|
4515
|
+
return cached;
|
|
4516
|
+
return this.fetchDatabase(databaseTag);
|
|
4517
|
+
}
|
|
4518
|
+
normalizeDatabaseTriggers(database) {
|
|
4519
|
+
const raw = database.triggers;
|
|
4520
|
+
if (!raw)
|
|
4521
|
+
return [];
|
|
4522
|
+
if (Array.isArray(raw))
|
|
4523
|
+
return raw;
|
|
4524
|
+
if (typeof raw === 'object')
|
|
4525
|
+
return Object.values(raw);
|
|
4526
|
+
return [];
|
|
4527
|
+
}
|
|
4350
4528
|
async deleteDatabase(tag) {
|
|
4351
4529
|
try {
|
|
4352
4530
|
const database = await this.fetchDatabase(tag);
|
|
@@ -4730,14 +4908,15 @@ class ProductsBuilderService {
|
|
|
4730
4908
|
}
|
|
4731
4909
|
}
|
|
4732
4910
|
async fetchDatabaseAction(tag, throwErrorIfExists = false) {
|
|
4911
|
+
var _a;
|
|
4733
4912
|
const [databaseTag, actionTag] = tag.split(':');
|
|
4734
4913
|
if (!databaseTag || !actionTag) {
|
|
4735
4914
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
4736
4915
|
}
|
|
4737
|
-
const database = this.
|
|
4916
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
4738
4917
|
if (!database)
|
|
4739
4918
|
throw new Error(`Database ${databaseTag} not found`);
|
|
4740
|
-
const action = database.actions.find((data) => data.tag === actionTag);
|
|
4919
|
+
const action = ((_a = database.actions) !== null && _a !== void 0 ? _a : []).find((data) => data.tag === actionTag);
|
|
4741
4920
|
if (!action && throwErrorIfExists)
|
|
4742
4921
|
throw new Error(`Database action ${tag} not found`);
|
|
4743
4922
|
if (database.type === productsBuilder_types_1.DatabaseTypes.MONGODB && action) {
|
|
@@ -4790,10 +4969,11 @@ class ProductsBuilderService {
|
|
|
4790
4969
|
}
|
|
4791
4970
|
}
|
|
4792
4971
|
async fetchDatabaseActions(databaseTag) {
|
|
4793
|
-
|
|
4972
|
+
var _a;
|
|
4973
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
4794
4974
|
if (!database)
|
|
4795
4975
|
throw new Error(`Database ${databaseTag} not found`);
|
|
4796
|
-
const actions = database.actions;
|
|
4976
|
+
const actions = (_a = database.actions) !== null && _a !== void 0 ? _a : [];
|
|
4797
4977
|
if (database.type === productsBuilder_types_1.DatabaseTypes.MONGODB && actions.length) {
|
|
4798
4978
|
/*return actions.map((data)=>{
|
|
4799
4979
|
return{ ...data,template: JSON.parse(String(data.template))}
|
|
@@ -4897,24 +5077,25 @@ class ProductsBuilderService {
|
|
|
4897
5077
|
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, existing), data), { value: processedValue || existing.value, databaseTag, component: enums_1.ProductComponents.DATABASE_MIGRATION }), this.getUserAccess());
|
|
4898
5078
|
}
|
|
4899
5079
|
async fetchDatabaseMigration(tag, throwError = false) {
|
|
5080
|
+
var _a;
|
|
4900
5081
|
const [databaseTag, migrationTag] = tag.split(':');
|
|
4901
5082
|
if (!databaseTag || !migrationTag) {
|
|
4902
5083
|
throw new Error(`tag is expected to be defined as "database_tag:action_tag"`);
|
|
4903
5084
|
}
|
|
4904
|
-
const database = this.
|
|
5085
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
4905
5086
|
if (!database)
|
|
4906
5087
|
throw new Error(`Database ${databaseTag} not found`);
|
|
4907
|
-
const migration = database.migrations.find((data) => data.tag === migrationTag);
|
|
5088
|
+
const migration = ((_a = database.migrations) !== null && _a !== void 0 ? _a : []).find((data) => data.tag === migrationTag);
|
|
4908
5089
|
if (!migration && throwError)
|
|
4909
5090
|
throw new Error(`Database migration ${tag} not found`);
|
|
4910
5091
|
return migration;
|
|
4911
5092
|
}
|
|
4912
5093
|
async fetchDatabaseMigrations(databaseTag) {
|
|
4913
|
-
|
|
5094
|
+
var _a;
|
|
5095
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
4914
5096
|
if (!database)
|
|
4915
5097
|
throw new Error(`Database ${databaseTag} not found`);
|
|
4916
|
-
|
|
4917
|
-
return migrations;
|
|
5098
|
+
return (_a = database.migrations) !== null && _a !== void 0 ? _a : [];
|
|
4918
5099
|
}
|
|
4919
5100
|
async deleteDatabaseMigration(tag) {
|
|
4920
5101
|
try {
|
|
@@ -4992,21 +5173,19 @@ class ProductsBuilderService {
|
|
|
4992
5173
|
if (!databaseTag || !triggerTag) {
|
|
4993
5174
|
throw new Error(`tag is expected to be defined as "database_tag:trigger_tag"`);
|
|
4994
5175
|
}
|
|
4995
|
-
const database = this.
|
|
5176
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
4996
5177
|
if (!database)
|
|
4997
5178
|
throw new Error(`Database ${databaseTag} not found`);
|
|
4998
|
-
const
|
|
4999
|
-
const trigger = triggers.find((data) => data.tag === triggerTag);
|
|
5179
|
+
const trigger = this.normalizeDatabaseTriggers(database).find((data) => data.tag === triggerTag);
|
|
5000
5180
|
if (!trigger && throwError)
|
|
5001
5181
|
throw new Error(`Database trigger ${tag} not found`);
|
|
5002
5182
|
return trigger || null;
|
|
5003
5183
|
}
|
|
5004
5184
|
async fetchDatabaseTriggers(databaseTag) {
|
|
5005
|
-
const database = this.
|
|
5185
|
+
const database = await this.resolveDatabaseConfig(databaseTag);
|
|
5006
5186
|
if (!database)
|
|
5007
5187
|
throw new Error(`Database ${databaseTag} not found`);
|
|
5008
|
-
|
|
5009
|
-
return triggers;
|
|
5188
|
+
return this.normalizeDatabaseTriggers(database);
|
|
5010
5189
|
}
|
|
5011
5190
|
async deleteDatabaseTrigger(tag) {
|
|
5012
5191
|
try {
|