@ductape/sdk 0.1.20 → 0.1.21
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
|
@@ -170,6 +170,26 @@ class GraphService {
|
|
|
170
170
|
access_key: this.config.access_key,
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Get or create a ProductBuilder without prefetching product metadata (use bootstrap on connect).
|
|
175
|
+
*/
|
|
176
|
+
getOrCreateProductBuilder(productTag) {
|
|
177
|
+
let builder = this.productBuilders.get(productTag);
|
|
178
|
+
if (!builder) {
|
|
179
|
+
builder = this.createNewProductBuilder();
|
|
180
|
+
this.productBuilders.set(productTag, builder);
|
|
181
|
+
}
|
|
182
|
+
return builder;
|
|
183
|
+
}
|
|
184
|
+
cacheBootstrapProductContext(productTag, boot) {
|
|
185
|
+
var _a;
|
|
186
|
+
if (boot.product_id) {
|
|
187
|
+
this.productId = boot.product_id;
|
|
188
|
+
}
|
|
189
|
+
if ((_a = boot.private_key) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
190
|
+
this.privateKeys.set(productTag, boot.private_key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
173
193
|
/**
|
|
174
194
|
* Get or create a ProductBuilder instance for the given product tag
|
|
175
195
|
*/
|
|
@@ -676,9 +696,7 @@ class GraphService {
|
|
|
676
696
|
let adapter = this.adapters.get(contextKey);
|
|
677
697
|
let context = this.connectionContexts.get(contextKey);
|
|
678
698
|
if (!adapter || !context) {
|
|
679
|
-
|
|
680
|
-
await this.getProductBuilder(config.product);
|
|
681
|
-
const graphConfig = await this.fetchGraphFromProduct(config.product, config.graph);
|
|
699
|
+
const graphConfig = await this.bootstrapGraphForConnect(config.product, config.graph, config.env);
|
|
682
700
|
if (!graphConfig) {
|
|
683
701
|
throw graph_error_1.GraphError.notFoundError(`Graph '${config.graph}' not found in product '${config.product}'`);
|
|
684
702
|
}
|
|
@@ -733,9 +751,7 @@ class GraphService {
|
|
|
733
751
|
let adapter = this.adapters.get(contextKey);
|
|
734
752
|
let context = this.connectionContexts.get(contextKey);
|
|
735
753
|
if (!adapter || !context) {
|
|
736
|
-
|
|
737
|
-
await this.getProductBuilder(config.product);
|
|
738
|
-
const graphConfig = await this.fetchGraphFromProduct(config.product, config.graph);
|
|
754
|
+
const graphConfig = await this.bootstrapGraphForConnect(config.product, config.graph, config.env);
|
|
739
755
|
if (!graphConfig) {
|
|
740
756
|
throw graph_error_1.GraphError.notFoundError(`Graph '${config.graph}' not found in product '${config.product}'`);
|
|
741
757
|
}
|
|
@@ -863,7 +879,7 @@ class GraphService {
|
|
|
863
879
|
lastGraphConnectLogAt.set(logKey, Object.assign(Object.assign({}, lastFail), { failed: end }));
|
|
864
880
|
this.logService.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
865
881
|
end, message: 'Graph connect - failed', failed_execution: true, data: { graph: config.graph, env: config.env, error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
866
|
-
|
|
882
|
+
this.logService.publish().catch(() => { });
|
|
867
883
|
}
|
|
868
884
|
throw error;
|
|
869
885
|
}
|
|
@@ -984,7 +1000,7 @@ class GraphService {
|
|
|
984
1000
|
const end = Date.now();
|
|
985
1001
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
986
1002
|
end, message: 'Graph createNode - failed', failed_execution: true, data: { labels: resolvedOptions.labels, operation: 'createNode', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
987
|
-
|
|
1003
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
988
1004
|
throw error;
|
|
989
1005
|
}
|
|
990
1006
|
}
|
|
@@ -1084,7 +1100,7 @@ class GraphService {
|
|
|
1084
1100
|
const end = Date.now();
|
|
1085
1101
|
(_p = this.logService) === null || _p === void 0 ? void 0 : _p.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1086
1102
|
end, message: 'Graph findNodes - failed', failed_execution: true, data: { labels: resolvedOptions.labels, operation: 'findNodes', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1087
|
-
|
|
1103
|
+
(_q = this.logService) === null || _q === void 0 ? void 0 : _q.publish().catch(() => { });
|
|
1088
1104
|
throw error;
|
|
1089
1105
|
}
|
|
1090
1106
|
}
|
|
@@ -1147,7 +1163,7 @@ class GraphService {
|
|
|
1147
1163
|
const end = Date.now();
|
|
1148
1164
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1149
1165
|
end, message: 'Graph updateNode - failed', failed_execution: true, data: { id: resolvedOptions.id, operation: 'updateNode', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1150
|
-
|
|
1166
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1151
1167
|
throw error;
|
|
1152
1168
|
}
|
|
1153
1169
|
}
|
|
@@ -1200,7 +1216,7 @@ class GraphService {
|
|
|
1200
1216
|
const end = Date.now();
|
|
1201
1217
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1202
1218
|
end, message: 'Graph deleteNode - failed', failed_execution: true, data: { id: resolvedOptions.id, operation: 'deleteNode', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1203
|
-
|
|
1219
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1204
1220
|
throw error;
|
|
1205
1221
|
}
|
|
1206
1222
|
}
|
|
@@ -1324,7 +1340,7 @@ class GraphService {
|
|
|
1324
1340
|
const end = Date.now();
|
|
1325
1341
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1326
1342
|
end, message: 'Graph createRelationship - failed', failed_execution: true, data: { type: resolvedOptions.type, operation: 'createRelationship', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1327
|
-
|
|
1343
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1328
1344
|
throw error;
|
|
1329
1345
|
}
|
|
1330
1346
|
}
|
|
@@ -1377,7 +1393,7 @@ class GraphService {
|
|
|
1377
1393
|
const end = Date.now();
|
|
1378
1394
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1379
1395
|
end, message: 'Graph findRelationships - failed', failed_execution: true, data: { type: resolvedOptions.type, operation: 'findRelationships', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1380
|
-
|
|
1396
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1381
1397
|
throw error;
|
|
1382
1398
|
}
|
|
1383
1399
|
}
|
|
@@ -1439,7 +1455,7 @@ class GraphService {
|
|
|
1439
1455
|
const end = Date.now();
|
|
1440
1456
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1441
1457
|
end, message: 'Graph updateRelationship - failed', failed_execution: true, data: { id: resolvedOptions.id, operation: 'updateRelationship', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1442
|
-
|
|
1458
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1443
1459
|
throw error;
|
|
1444
1460
|
}
|
|
1445
1461
|
}
|
|
@@ -1492,7 +1508,7 @@ class GraphService {
|
|
|
1492
1508
|
const end = Date.now();
|
|
1493
1509
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1494
1510
|
end, message: 'Graph deleteRelationship - failed', failed_execution: true, data: { id: resolvedOptions.id, operation: 'deleteRelationship', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1495
|
-
|
|
1511
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1496
1512
|
throw error;
|
|
1497
1513
|
}
|
|
1498
1514
|
}
|
|
@@ -1545,7 +1561,7 @@ class GraphService {
|
|
|
1545
1561
|
const end = Date.now();
|
|
1546
1562
|
(_h = this.logService) === null || _h === void 0 ? void 0 : _h.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1547
1563
|
end, message: 'Graph traverse - failed', failed_execution: true, data: { startNodeId: options.startNodeId, operation: 'traverse', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1548
|
-
|
|
1564
|
+
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.publish().catch(() => { });
|
|
1549
1565
|
throw error;
|
|
1550
1566
|
}
|
|
1551
1567
|
}
|
|
@@ -1642,7 +1658,7 @@ class GraphService {
|
|
|
1642
1658
|
const end = Date.now();
|
|
1643
1659
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1644
1660
|
end, message: 'Graph countNodes - failed', failed_execution: true, data: { labels, operation: 'countNodes', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1645
|
-
|
|
1661
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1646
1662
|
throw error;
|
|
1647
1663
|
}
|
|
1648
1664
|
}
|
|
@@ -1702,7 +1718,7 @@ class GraphService {
|
|
|
1702
1718
|
const end = Date.now();
|
|
1703
1719
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1704
1720
|
end, message: 'Graph getStatistics - failed', failed_execution: true, data: { operation: 'getStatistics', error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1705
|
-
|
|
1721
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1706
1722
|
throw error;
|
|
1707
1723
|
}
|
|
1708
1724
|
}
|
|
@@ -1774,7 +1790,7 @@ class GraphService {
|
|
|
1774
1790
|
const end = Date.now();
|
|
1775
1791
|
(_j = this.logService) === null || _j === void 0 ? void 0 : _j.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1776
1792
|
end, message: 'Graph query - failed', failed_execution: true, data: { operation: 'query', graph: graphValue, env: envValue, error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
1777
|
-
|
|
1793
|
+
(_k = this.logService) === null || _k === void 0 ? void 0 : _k.publish().catch(() => { });
|
|
1778
1794
|
throw error;
|
|
1779
1795
|
}
|
|
1780
1796
|
}
|
|
@@ -2127,7 +2143,7 @@ class GraphService {
|
|
|
2127
2143
|
if (!action) {
|
|
2128
2144
|
const end = Date.now();
|
|
2129
2145
|
(_c = this.logService) === null || _c === void 0 ? void 0 : _c.add(Object.assign(Object.assign({}, baseLogs), { start: startTime, end, message: 'Graph action execute - failed', failed_execution: true, data: { graph: options.graph, action: options.action, error: `Action '${options.action}' not found` }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
2130
|
-
|
|
2146
|
+
(_d = this.logService) === null || _d === void 0 ? void 0 : _d.publish().catch(() => { });
|
|
2131
2147
|
return {
|
|
2132
2148
|
success: false,
|
|
2133
2149
|
executionTime: end - startTime,
|
|
@@ -2154,7 +2170,7 @@ class GraphService {
|
|
|
2154
2170
|
catch (error) {
|
|
2155
2171
|
const end = Date.now();
|
|
2156
2172
|
(_g = this.logService) === null || _g === void 0 ? void 0 : _g.add(Object.assign(Object.assign({}, baseLogs), { start: startTime, end, message: 'Graph action execute - failed', failed_execution: true, data: { graph: options.graph, action: options.action, error: error.message || 'Execution failed' }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
2157
|
-
|
|
2173
|
+
(_h = this.logService) === null || _h === void 0 ? void 0 : _h.publish().catch(() => { });
|
|
2158
2174
|
return {
|
|
2159
2175
|
success: false,
|
|
2160
2176
|
executionTime: end - startTime,
|
|
@@ -2361,7 +2377,7 @@ class GraphService {
|
|
|
2361
2377
|
const end = Date.now();
|
|
2362
2378
|
(_e = this.logService) === null || _e === void 0 ? void 0 : _e.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
2363
2379
|
end, message: 'Graph dispatch - failed', failed_execution: true, data: { graph: data.graph, operation: data.operation, error: String(error) }, status: logs_types_1.LogEventStatus.FAIL }));
|
|
2364
|
-
|
|
2380
|
+
(_f = this.logService) === null || _f === void 0 ? void 0 : _f.publish().catch(() => { });
|
|
2365
2381
|
throw error;
|
|
2366
2382
|
}
|
|
2367
2383
|
}
|
|
@@ -2533,10 +2549,12 @@ class GraphService {
|
|
|
2533
2549
|
return;
|
|
2534
2550
|
const contextKey = `${options.graph}:${options.env}`;
|
|
2535
2551
|
const existingAdapter = this.adapters.get(contextKey);
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2552
|
+
if (existingAdapter) {
|
|
2553
|
+
const ctx = this.connectionContexts.get(contextKey);
|
|
2554
|
+
if (ctx) {
|
|
2555
|
+
this.currentContext = ctx;
|
|
2556
|
+
this.transactionManager = new transaction_manager_1.GraphTransactionManager(existingAdapter);
|
|
2557
|
+
}
|
|
2540
2558
|
return;
|
|
2541
2559
|
}
|
|
2542
2560
|
await this.connect({ graph: options.graph, env: options.env, product: options.product });
|
|
@@ -2607,8 +2625,6 @@ class GraphService {
|
|
|
2607
2625
|
let lastError = null;
|
|
2608
2626
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
2609
2627
|
try {
|
|
2610
|
-
// Ensure we have a connected adapter before each attempt
|
|
2611
|
-
await this.getAdapterWithReconnect();
|
|
2612
2628
|
return await operation();
|
|
2613
2629
|
}
|
|
2614
2630
|
catch (error) {
|
|
@@ -2622,6 +2638,7 @@ class GraphService {
|
|
|
2622
2638
|
if (this.currentContext) {
|
|
2623
2639
|
this.currentContext.connected = false;
|
|
2624
2640
|
}
|
|
2641
|
+
await this.attemptReconnect();
|
|
2625
2642
|
// Small delay before retry (exponential backoff)
|
|
2626
2643
|
await new Promise(resolve => setTimeout(resolve, 500 * (attempt + 1)));
|
|
2627
2644
|
}
|
|
@@ -2662,9 +2679,28 @@ class GraphService {
|
|
|
2662
2679
|
errorMessage.includes('no longer valid') ||
|
|
2663
2680
|
errorMessage.includes('pool is closed'));
|
|
2664
2681
|
}
|
|
2665
|
-
/**
|
|
2666
|
-
|
|
2667
|
-
|
|
2682
|
+
/** Single bootstrap API call for connect — product + graph config + private_key. */
|
|
2683
|
+
async bootstrapGraphForConnect(productTag, graphTag, envSlug) {
|
|
2684
|
+
var _a;
|
|
2685
|
+
if (!(envSlug === null || envSlug === void 0 ? void 0 : envSlug.trim())) {
|
|
2686
|
+
throw graph_error_1.GraphError.validationError('env is required for graph connect');
|
|
2687
|
+
}
|
|
2688
|
+
const builder = this.getOrCreateProductBuilder(productTag);
|
|
2689
|
+
const boot = await builder.bootstrapGraph({
|
|
2690
|
+
product_tag: productTag,
|
|
2691
|
+
env_slug: envSlug,
|
|
2692
|
+
graph_tag: graphTag,
|
|
2693
|
+
});
|
|
2694
|
+
this.cacheBootstrapProductContext(productTag, boot);
|
|
2695
|
+
if (!(boot === null || boot === void 0 ? void 0 : boot.graph)) {
|
|
2696
|
+
throw graph_error_1.GraphError.notFoundError(`Graph '${graphTag}' not found in product '${productTag}'`);
|
|
2697
|
+
}
|
|
2698
|
+
const graph = boot.graph;
|
|
2699
|
+
if (boot.private_key && ((_a = graph.envs) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
2700
|
+
graph.envs = graph.envs.map((env) => (Object.assign(Object.assign({}, env), { connection_url: env.connection_url ? (0, processor_utils_1.decrypt)(env.connection_url, boot.private_key) : env.connection_url, username: env.username ? (0, processor_utils_1.decrypt)(env.username, boot.private_key) : env.username, password: env.password ? (0, processor_utils_1.decrypt)(env.password, boot.private_key) : env.password, graphName: env.graphName ? (0, processor_utils_1.decrypt)(env.graphName, boot.private_key) : env.graphName, region: env.region ? (0, processor_utils_1.decrypt)(env.region, boot.private_key) : env.region })));
|
|
2701
|
+
}
|
|
2702
|
+
return this.productGraphToConfig(graph);
|
|
2703
|
+
}
|
|
2668
2704
|
async fetchGraphFromProduct(productTag, graphTag) {
|
|
2669
2705
|
try {
|
|
2670
2706
|
const builder = await this.getProductBuilder(productTag);
|