@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
|
@@ -196,6 +196,26 @@ class DatabaseService {
|
|
|
196
196
|
access_key: this.config.access_key,
|
|
197
197
|
});
|
|
198
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Get or create a ProductBuilder without prefetching product metadata (use bootstrap on connect).
|
|
201
|
+
*/
|
|
202
|
+
getOrCreateProductBuilder(productTag) {
|
|
203
|
+
let builder = this.productBuilders.get(productTag);
|
|
204
|
+
if (!builder) {
|
|
205
|
+
builder = this.createNewProductBuilder();
|
|
206
|
+
this.productBuilders.set(productTag, builder);
|
|
207
|
+
}
|
|
208
|
+
return builder;
|
|
209
|
+
}
|
|
210
|
+
cacheBootstrapProductContext(productTag, boot) {
|
|
211
|
+
var _a;
|
|
212
|
+
if (boot.product_id) {
|
|
213
|
+
this.productId = boot.product_id;
|
|
214
|
+
}
|
|
215
|
+
if ((_a = boot.private_key) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
216
|
+
this.privateKeys.set(productTag, boot.private_key);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
199
219
|
/**
|
|
200
220
|
* Get or create a ProductBuilder instance for the given product tag
|
|
201
221
|
*/
|
|
@@ -277,6 +297,28 @@ class DatabaseService {
|
|
|
277
297
|
const builder = await this.getProductBuilder(productTag);
|
|
278
298
|
return builder.fetchDatabase(databaseTag);
|
|
279
299
|
}
|
|
300
|
+
/** Single bootstrap API call for connect — product + database config + private_key. */
|
|
301
|
+
async bootstrapDatabaseForConnect(productTag, databaseTag, envSlug) {
|
|
302
|
+
var _a;
|
|
303
|
+
if (!(envSlug === null || envSlug === void 0 ? void 0 : envSlug.trim())) {
|
|
304
|
+
throw new database_error_1.DatabaseError('env is required for database connect', enums_1.DatabaseErrorType.VALIDATION_ERROR);
|
|
305
|
+
}
|
|
306
|
+
const builder = this.getOrCreateProductBuilder(productTag);
|
|
307
|
+
const boot = await builder.bootstrapDatabase({
|
|
308
|
+
product_tag: productTag,
|
|
309
|
+
env_slug: envSlug,
|
|
310
|
+
database_tag: databaseTag,
|
|
311
|
+
});
|
|
312
|
+
this.cacheBootstrapProductContext(productTag, boot);
|
|
313
|
+
if (!(boot === null || boot === void 0 ? void 0 : boot.database)) {
|
|
314
|
+
throw new database_error_1.DatabaseError(`Database '${databaseTag}' not found for product '${productTag}'.`, enums_1.DatabaseErrorType.NOT_FOUND);
|
|
315
|
+
}
|
|
316
|
+
const database = boot.database;
|
|
317
|
+
if (boot.private_key && ((_a = database.envs) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
318
|
+
database.envs = database.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 })));
|
|
319
|
+
}
|
|
320
|
+
return database;
|
|
321
|
+
}
|
|
280
322
|
/**
|
|
281
323
|
* Update a database configuration
|
|
282
324
|
* @param productTag - The product tag
|
|
@@ -699,8 +741,7 @@ class DatabaseService {
|
|
|
699
741
|
if (!config.product) {
|
|
700
742
|
throw new database_error_1.DatabaseError(`Database '${config.database}' not found locally. Please provide 'product' to fetch from remote.`, enums_1.DatabaseErrorType.NOT_FOUND);
|
|
701
743
|
}
|
|
702
|
-
await this.
|
|
703
|
-
const dbConfig = await this.fetchDatabase(config.product, config.database);
|
|
744
|
+
const dbConfig = await this.bootstrapDatabaseForConnect(config.product, config.database, config.env);
|
|
704
745
|
if (!dbConfig) {
|
|
705
746
|
throw new database_error_1.DatabaseError(`Database '${config.database}' not found for product '${config.product}'.`, enums_1.DatabaseErrorType.NOT_FOUND);
|
|
706
747
|
}
|
|
@@ -786,8 +827,7 @@ class DatabaseService {
|
|
|
786
827
|
if (!config.product) {
|
|
787
828
|
throw new database_error_1.DatabaseError(`Database '${config.database}' not found locally. Please provide 'product' to fetch from remote.`, enums_1.DatabaseErrorType.NOT_FOUND);
|
|
788
829
|
}
|
|
789
|
-
await this.
|
|
790
|
-
const dbConfig = await this.fetchDatabase(config.product, config.database);
|
|
830
|
+
const dbConfig = await this.bootstrapDatabaseForConnect(config.product, config.database, config.env);
|
|
791
831
|
if (!dbConfig) {
|
|
792
832
|
throw new database_error_1.DatabaseError(`Database '${config.database}' not found for product '${config.product}'.`, enums_1.DatabaseErrorType.NOT_FOUND);
|
|
793
833
|
}
|
|
@@ -851,7 +891,7 @@ class DatabaseService {
|
|
|
851
891
|
try {
|
|
852
892
|
let connectionUrl = context.connectionUrl;
|
|
853
893
|
let vpcTunnelOptions = {};
|
|
854
|
-
if (this.config &&
|
|
894
|
+
if (this.config && context.authMode === 'cloud_connection') {
|
|
855
895
|
const runtimeAuth = {
|
|
856
896
|
token: this.config.token,
|
|
857
897
|
public_key: this.config.public_key,
|
|
@@ -1170,11 +1210,11 @@ class DatabaseService {
|
|
|
1170
1210
|
return cached.data;
|
|
1171
1211
|
}
|
|
1172
1212
|
}
|
|
1173
|
-
await this.
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1213
|
+
const result = await this.withAdapterRetry(resolvedOptions, async (adapter) => {
|
|
1214
|
+
const queryBuilder = new query_builder_1.QueryBuilder(adapter.getDatabaseType());
|
|
1215
|
+
const builtQuery = queryBuilder.buildQuery(resolvedOptions);
|
|
1216
|
+
return adapter.query(builtQuery);
|
|
1217
|
+
});
|
|
1178
1218
|
// Store in cache if cache tag is provided
|
|
1179
1219
|
if (options.cache && this.cacheManager && privateKey && productTag) {
|
|
1180
1220
|
const cacheConfig = await this.validateCache(productTag, options.cache);
|
|
@@ -1274,9 +1314,7 @@ class DatabaseService {
|
|
|
1274
1314
|
return cached.data;
|
|
1275
1315
|
}
|
|
1276
1316
|
}
|
|
1277
|
-
await this.
|
|
1278
|
-
const adapter = this.getAdapter(options);
|
|
1279
|
-
const result = await adapter.raw(options);
|
|
1317
|
+
const result = await this.withAdapterRetry(options, async (adapter) => adapter.raw(options));
|
|
1280
1318
|
// Store in cache if cache tag is provided
|
|
1281
1319
|
if (options.cache && this.cacheManager && privateKey && options.product) {
|
|
1282
1320
|
const cacheConfig = await this.validateCache(options.product, options.cache);
|
|
@@ -1388,9 +1426,7 @@ class DatabaseService {
|
|
|
1388
1426
|
const preSaveResult = await processor.process(resolvedOptions.data, resolvedOptions.preSave);
|
|
1389
1427
|
processedData = preSaveResult.data;
|
|
1390
1428
|
}
|
|
1391
|
-
await this.
|
|
1392
|
-
const adapter = this.getAdapter(resolvedOptions);
|
|
1393
|
-
const result = await adapter.insert(Object.assign(Object.assign({}, resolvedOptions), { data: processedData }));
|
|
1429
|
+
const result = await this.withAdapterRetry(resolvedOptions, async (adapter) => adapter.insert(Object.assign(Object.assign({}, resolvedOptions), { data: processedData })));
|
|
1394
1430
|
const end = Date.now();
|
|
1395
1431
|
(_f = this.logService) === null || _f === void 0 ? void 0 : _f.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1396
1432
|
end, message: 'Database insert - success', successful_execution: true, status: logs_types_1.LogEventStatus.SUCCESS }));
|
|
@@ -1470,9 +1506,7 @@ class DatabaseService {
|
|
|
1470
1506
|
const preSaveResult = await processor.process(resolvedOptions.data, resolvedOptions.preSave);
|
|
1471
1507
|
processedData = preSaveResult.data;
|
|
1472
1508
|
}
|
|
1473
|
-
await this.
|
|
1474
|
-
const adapter = this.getAdapter(resolvedOptions);
|
|
1475
|
-
const result = await adapter.update(Object.assign(Object.assign({}, resolvedOptions), { data: processedData }));
|
|
1509
|
+
const result = await this.withAdapterRetry(resolvedOptions, async (adapter) => adapter.update(Object.assign(Object.assign({}, resolvedOptions), { data: processedData })));
|
|
1476
1510
|
const end = Date.now();
|
|
1477
1511
|
(_f = this.logService) === null || _f === void 0 ? void 0 : _f.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1478
1512
|
end, message: 'Database update - success', successful_execution: true, status: logs_types_1.LogEventStatus.SUCCESS }));
|
|
@@ -1535,9 +1569,7 @@ class DatabaseService {
|
|
|
1535
1569
|
} }, sessionLogFields);
|
|
1536
1570
|
(_e = this.logService) === null || _e === void 0 ? void 0 : _e.add(Object.assign(Object.assign({}, baseLogs), { start, message: 'Database delete - initiated', status: logs_types_1.LogEventStatus.PROCESSING }));
|
|
1537
1571
|
try {
|
|
1538
|
-
await this.
|
|
1539
|
-
const adapter = this.getAdapter(resolvedOptions);
|
|
1540
|
-
const result = await adapter.delete(resolvedOptions);
|
|
1572
|
+
const result = await this.withAdapterRetry(resolvedOptions, async (adapter) => adapter.delete(resolvedOptions));
|
|
1541
1573
|
const end = Date.now();
|
|
1542
1574
|
(_f = this.logService) === null || _f === void 0 ? void 0 : _f.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1543
1575
|
end, message: 'Database delete - success', successful_execution: true, status: logs_types_1.LogEventStatus.SUCCESS }));
|
|
@@ -1608,9 +1640,7 @@ class DatabaseService {
|
|
|
1608
1640
|
} }, sessionLogFields);
|
|
1609
1641
|
(_e = this.logService) === null || _e === void 0 ? void 0 : _e.add(Object.assign(Object.assign({}, baseLogs), { start, message: 'Database upsert - initiated', status: logs_types_1.LogEventStatus.PROCESSING }));
|
|
1610
1642
|
try {
|
|
1611
|
-
await this.
|
|
1612
|
-
const adapter = this.getAdapter(resolvedOptions);
|
|
1613
|
-
const result = await adapter.upsert(resolvedOptions);
|
|
1643
|
+
const result = await this.withAdapterRetry(resolvedOptions, async (adapter) => adapter.upsert(resolvedOptions));
|
|
1614
1644
|
const end = Date.now();
|
|
1615
1645
|
(_f = this.logService) === null || _f === void 0 ? void 0 : _f.add(Object.assign(Object.assign({}, baseLogs), { start,
|
|
1616
1646
|
end, message: 'Database upsert - success', successful_execution: true, status: logs_types_1.LogEventStatus.SUCCESS }));
|
|
@@ -2577,7 +2607,7 @@ class DatabaseService {
|
|
|
2577
2607
|
return adapter;
|
|
2578
2608
|
}
|
|
2579
2609
|
/**
|
|
2580
|
-
* Ensure an adapter exists for the given database/env/product (connect on
|
|
2610
|
+
* Ensure an adapter exists for the given database/env/product (lazy connect on failure).
|
|
2581
2611
|
* Use before getAdapter() when options include database+env+product (e.g. from proxy).
|
|
2582
2612
|
*/
|
|
2583
2613
|
async ensureAdapterFor(options) {
|
|
@@ -2587,7 +2617,34 @@ class DatabaseService {
|
|
|
2587
2617
|
const existing = this.adapters.get(contextKey);
|
|
2588
2618
|
if (existing && typeof existing.isConnected === 'function' && existing.isConnected())
|
|
2589
2619
|
return;
|
|
2590
|
-
|
|
2620
|
+
if (existing)
|
|
2621
|
+
return;
|
|
2622
|
+
if (!this.connectionContexts.get(contextKey)) {
|
|
2623
|
+
await this.connect({ database: options.database, env: options.env, product: options.product });
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
isConnectionError(error) {
|
|
2627
|
+
var _a, _b;
|
|
2628
|
+
const message = String((_b = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error) !== null && _b !== void 0 ? _b : '').toLowerCase();
|
|
2629
|
+
return ['connection', 'connect', 'closed', 'reset', 'timeout', 'refused', 'broken pipe', 'not connected', 'eof', 'network']
|
|
2630
|
+
.some((needle) => message.includes(needle));
|
|
2631
|
+
}
|
|
2632
|
+
async withAdapterRetry(options, fn) {
|
|
2633
|
+
await this.ensureAdapterFor(options);
|
|
2634
|
+
const adapter = this.getAdapter(options);
|
|
2635
|
+
try {
|
|
2636
|
+
return await fn(adapter);
|
|
2637
|
+
}
|
|
2638
|
+
catch (error) {
|
|
2639
|
+
if (!this.isConnectionError(error))
|
|
2640
|
+
throw error;
|
|
2641
|
+
await this.connect({
|
|
2642
|
+
database: options.database,
|
|
2643
|
+
env: options.env,
|
|
2644
|
+
product: options.product,
|
|
2645
|
+
});
|
|
2646
|
+
return await fn(this.getAdapter(options));
|
|
2647
|
+
}
|
|
2591
2648
|
}
|
|
2592
2649
|
/**
|
|
2593
2650
|
* Get the current connection context
|