@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.
Files changed (79) hide show
  1. package/dist/agents/agents.service.d.ts +2 -0
  2. package/dist/agents/agents.service.js +26 -3
  3. package/dist/agents/agents.service.js.map +1 -1
  4. package/dist/api/services/logsApi.service.js +5 -1
  5. package/dist/api/services/logsApi.service.js.map +1 -1
  6. package/dist/api/services/productsApi.service.d.ts +111 -0
  7. package/dist/api/services/productsApi.service.js +90 -0
  8. package/dist/api/services/productsApi.service.js.map +1 -1
  9. package/dist/api/urls.d.ts +7 -0
  10. package/dist/api/urls.js +14 -7
  11. package/dist/api/urls.js.map +1 -1
  12. package/dist/apps/services/app.service.js +7 -2
  13. package/dist/apps/services/app.service.js.map +1 -1
  14. package/dist/brokers/brokers.service.js +20 -12
  15. package/dist/brokers/brokers.service.js.map +1 -1
  16. package/dist/database/adapters/mysql.adapter.js +8 -3
  17. package/dist/database/adapters/mysql.adapter.js.map +1 -1
  18. package/dist/database/adapters/postgresql.adapter.js +6 -2
  19. package/dist/database/adapters/postgresql.adapter.js.map +1 -1
  20. package/dist/database/databases.service.d.ts +10 -1
  21. package/dist/database/databases.service.js +84 -27
  22. package/dist/database/databases.service.js.map +1 -1
  23. package/dist/graph/graphs.service.d.ts +7 -3
  24. package/dist/graph/graphs.service.js +67 -31
  25. package/dist/graph/graphs.service.js.map +1 -1
  26. package/dist/index.d.ts +9 -2
  27. package/dist/index.js +32 -93
  28. package/dist/index.js.map +1 -1
  29. package/dist/logs/logs.service.d.ts +3 -1
  30. package/dist/logs/logs.service.js +12 -2
  31. package/dist/logs/logs.service.js.map +1 -1
  32. package/dist/logs/logs.types.d.ts +4 -0
  33. package/dist/logs/logs.types.js.map +1 -1
  34. package/dist/notifications/notifications.service.d.ts +6 -0
  35. package/dist/notifications/notifications.service.js +54 -17
  36. package/dist/notifications/notifications.service.js.map +1 -1
  37. package/dist/processor/services/processor.service.d.ts +0 -14
  38. package/dist/processor/services/processor.service.js +6 -72
  39. package/dist/processor/services/processor.service.js.map +1 -1
  40. package/dist/products/bootstrap-cache.d.ts +22 -0
  41. package/dist/products/bootstrap-cache.js +78 -0
  42. package/dist/products/bootstrap-cache.js.map +1 -0
  43. package/dist/products/services/products.service.d.ts +46 -3
  44. package/dist/products/services/products.service.js +304 -125
  45. package/dist/products/services/products.service.js.map +1 -1
  46. package/dist/products/validators/joi-validators/create.productFallback.validator.js +1 -1
  47. package/dist/products/validators/joi-validators/create.productGraph.validator.js +7 -0
  48. package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -1
  49. package/dist/products/validators/joi-validators/create.productQuota.validator.js +1 -1
  50. package/dist/products/validators/joi-validators/create.productVector.validator.js +6 -0
  51. package/dist/products/validators/joi-validators/create.productVector.validator.js.map +1 -1
  52. package/dist/products/validators/joi-validators/update.productFallback.validator.js +1 -1
  53. package/dist/products/validators/joi-validators/update.productGraph.validator.js +9 -0
  54. package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -1
  55. package/dist/products/validators/joi-validators/update.productQuota.validator.js +1 -1
  56. package/dist/resilience/fallback.service.d.ts +3 -0
  57. package/dist/resilience/fallback.service.js +49 -14
  58. package/dist/resilience/fallback.service.js.map +1 -1
  59. package/dist/resilience/healthcheck.service.d.ts +3 -0
  60. package/dist/resilience/healthcheck.service.js +57 -7
  61. package/dist/resilience/healthcheck.service.js.map +1 -1
  62. package/dist/resilience/quota.service.d.ts +3 -0
  63. package/dist/resilience/quota.service.js +49 -14
  64. package/dist/resilience/quota.service.js.map +1 -1
  65. package/dist/resilience/resilience-execution.utils.d.ts +22 -0
  66. package/dist/resilience/resilience-execution.utils.js +81 -0
  67. package/dist/resilience/resilience-execution.utils.js.map +1 -0
  68. package/dist/sessions/sessions.service.d.ts +9 -1
  69. package/dist/sessions/sessions.service.js +125 -49
  70. package/dist/sessions/sessions.service.js.map +1 -1
  71. package/dist/types/index.types.d.ts +8 -0
  72. package/dist/types/index.types.js.map +1 -1
  73. package/dist/types/processor.types.d.ts +3 -0
  74. package/dist/types/processor.types.js.map +1 -1
  75. package/dist/types/requests.types.d.ts +4 -0
  76. package/dist/vector/vector-database.service.d.ts +6 -0
  77. package/dist/vector/vector-database.service.js +66 -8
  78. package/dist/vector/vector-database.service.js.map +1 -1
  79. 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.getProductBuilder(config.product);
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.getProductBuilder(config.product);
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 && (context.authMode === 'cloud_connection' || (0, secrets_1.isSecretReference)(connectionUrl).isSecret)) {
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.ensureAdapterFor(resolvedOptions);
1174
- const adapter = this.getAdapter(resolvedOptions);
1175
- const queryBuilder = new query_builder_1.QueryBuilder(adapter.getDatabaseType());
1176
- const builtQuery = queryBuilder.buildQuery(resolvedOptions);
1177
- const result = await adapter.query(builtQuery);
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.ensureAdapterFor(options);
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.ensureAdapterFor(resolvedOptions);
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.ensureAdapterFor(resolvedOptions);
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.ensureAdapterFor(resolvedOptions);
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.ensureAdapterFor(resolvedOptions);
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 demand).
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
- await this.connect({ database: options.database, env: options.env, product: options.product });
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