@ductape/sdk 0.1.7 → 0.1.9

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 (105) hide show
  1. package/dist/api/services/cloudApi.service.d.ts +31 -0
  2. package/dist/api/services/cloudApi.service.js +103 -0
  3. package/dist/api/services/cloudApi.service.js.map +1 -0
  4. package/dist/api/services/productsApi.service.d.ts +17 -0
  5. package/dist/api/services/productsApi.service.js +18 -4
  6. package/dist/api/services/productsApi.service.js.map +1 -1
  7. package/dist/api/urls.d.ts +9 -0
  8. package/dist/api/urls.js +13 -3
  9. package/dist/api/urls.js.map +1 -1
  10. package/dist/api/utils/integration-api-error.d.ts +6 -0
  11. package/dist/api/utils/integration-api-error.js +45 -0
  12. package/dist/api/utils/integration-api-error.js.map +1 -0
  13. package/dist/apps/utils/credential-manager.d.ts +2 -2
  14. package/dist/apps/utils/credential-manager.js +2 -2
  15. package/dist/apps/utils/oauth-manager.d.ts +5 -5
  16. package/dist/apps/utils/oauth-manager.js +5 -5
  17. package/dist/brokers/brokers.service.js +29 -8
  18. package/dist/brokers/brokers.service.js.map +1 -1
  19. package/dist/cache/cache.service.d.ts +2 -0
  20. package/dist/cache/cache.service.js +9 -4
  21. package/dist/cache/cache.service.js.map +1 -1
  22. package/dist/cache/types/index.d.ts +2 -0
  23. package/dist/cloud/cloud-runtime.util.d.ts +22 -0
  24. package/dist/cloud/cloud-runtime.util.js +61 -0
  25. package/dist/cloud/cloud-runtime.util.js.map +1 -0
  26. package/dist/cloud/cloud.service.d.ts +43 -0
  27. package/dist/cloud/cloud.service.js +121 -0
  28. package/dist/cloud/cloud.service.js.map +1 -0
  29. package/dist/cloud/index.d.ts +5 -0
  30. package/dist/cloud/index.js +25 -0
  31. package/dist/cloud/index.js.map +1 -0
  32. package/dist/cloud/types/cloud.types.d.ts +140 -0
  33. package/dist/cloud/types/cloud.types.js +6 -0
  34. package/dist/cloud/types/cloud.types.js.map +1 -0
  35. package/dist/cloud/types/index.d.ts +1 -0
  36. package/dist/cloud/types/index.js +18 -0
  37. package/dist/cloud/types/index.js.map +1 -0
  38. package/dist/database/databases.service.d.ts +30 -0
  39. package/dist/database/databases.service.js +86 -10
  40. package/dist/database/databases.service.js.map +1 -1
  41. package/dist/database/index.d.ts +1 -1
  42. package/dist/database/index.js.map +1 -1
  43. package/dist/database/types/connection.interface.d.ts +4 -0
  44. package/dist/graph/graphs.service.d.ts +16 -0
  45. package/dist/graph/graphs.service.js +110 -20
  46. package/dist/graph/graphs.service.js.map +1 -1
  47. package/dist/graph/index.d.ts +1 -0
  48. package/dist/graph/index.js.map +1 -1
  49. package/dist/graph/types/connection.interface.d.ts +12 -0
  50. package/dist/index.d.ts +225 -13
  51. package/dist/index.js +152 -114
  52. package/dist/index.js.map +1 -1
  53. package/dist/notifications/notifications.service.d.ts +2 -0
  54. package/dist/notifications/notifications.service.js +10 -5
  55. package/dist/notifications/notifications.service.js.map +1 -1
  56. package/dist/notifications/types/notifications.types.d.ts +2 -0
  57. package/dist/products/services/products.service.d.ts +3 -1
  58. package/dist/products/services/products.service.js +8 -0
  59. package/dist/products/services/products.service.js.map +1 -1
  60. package/dist/products/validators/joi-validators/update.dataValue.validator.js +2 -1
  61. package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
  62. package/dist/resilience/fallback.service.d.ts +2 -0
  63. package/dist/resilience/fallback.service.js +6 -1
  64. package/dist/resilience/fallback.service.js.map +1 -1
  65. package/dist/resilience/healthcheck.service.d.ts +2 -0
  66. package/dist/resilience/healthcheck.service.js +21 -14
  67. package/dist/resilience/healthcheck.service.js.map +1 -1
  68. package/dist/resilience/quota.service.d.ts +2 -0
  69. package/dist/resilience/quota.service.js +6 -1
  70. package/dist/resilience/quota.service.js.map +1 -1
  71. package/dist/resilience/types/index.d.ts +2 -0
  72. package/dist/runtime/runtime-defaults.d.ts +28 -0
  73. package/dist/runtime/runtime-defaults.js +38 -0
  74. package/dist/runtime/runtime-defaults.js.map +1 -0
  75. package/dist/sessions/sessions.service.d.ts +2 -0
  76. package/dist/sessions/sessions.service.js +15 -10
  77. package/dist/sessions/sessions.service.js.map +1 -1
  78. package/dist/sessions/types/index.d.ts +3 -0
  79. package/dist/storage/storage.service.d.ts +2 -0
  80. package/dist/storage/storage.service.js +43 -10
  81. package/dist/storage/storage.service.js.map +1 -1
  82. package/dist/storage/types/index.d.ts +3 -0
  83. package/dist/storage/utils/storage.util.js +42 -12
  84. package/dist/storage/utils/storage.util.js.map +1 -1
  85. package/dist/types/enums.d.ts +2 -1
  86. package/dist/types/enums.js +1 -0
  87. package/dist/types/enums.js.map +1 -1
  88. package/dist/types/index.types.d.ts +8 -1
  89. package/dist/types/index.types.js +9 -0
  90. package/dist/types/index.types.js.map +1 -1
  91. package/dist/types/productsBuilder.types.d.ts +24 -7
  92. package/dist/types/productsBuilder.types.js.map +1 -1
  93. package/dist/vector/index.d.ts +2 -1
  94. package/dist/vector/index.js +3 -1
  95. package/dist/vector/index.js.map +1 -1
  96. package/dist/vector/utils/index.d.ts +1 -0
  97. package/dist/vector/utils/index.js +3 -1
  98. package/dist/vector/utils/index.js.map +1 -1
  99. package/dist/vector/utils/metadata-schema.d.ts +14 -0
  100. package/dist/vector/utils/metadata-schema.js +79 -0
  101. package/dist/vector/utils/metadata-schema.js.map +1 -0
  102. package/dist/vector/vector-database.service.d.ts +27 -0
  103. package/dist/vector/vector-database.service.js +73 -2
  104. package/dist/vector/vector-database.service.js.map +1 -1
  105. package/package.json +6 -3
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Cloud provider connection and resource types (AWS, GCP, Azure).
3
+ */
4
+ /** Supported cloud providers */
5
+ export type CloudProvider = 'aws' | 'gcp' | 'azure';
6
+ /** How the cloud account is linked to Ductape */
7
+ export type CloudAuthMode = 'iam_role' | 'oauth' | 'service_principal' | 'workload_identity';
8
+ /** Connection lifecycle status */
9
+ export type CloudConnectionStatus = 'pending' | 'active' | 'error' | 'revoked';
10
+ /** Scopes gate which resource types can be listed/imported */
11
+ export type CloudConnectionScope = 'storage' | 'broker' | 'database' | 'graph' | 'vector' | 'cache';
12
+ /** Workspace cloud connection record */
13
+ export interface ICloudConnection {
14
+ id: string;
15
+ workspace_id: string;
16
+ provider: CloudProvider;
17
+ display_name: string;
18
+ account_identifier: string;
19
+ auth_mode: CloudAuthMode;
20
+ status: CloudConnectionStatus;
21
+ scopes: CloudConnectionScope[];
22
+ metadata?: Record<string, unknown>;
23
+ created_by?: string;
24
+ created_at?: string;
25
+ updated_at?: string;
26
+ }
27
+ export interface ICreateCloudConnectionInput {
28
+ provider: CloudProvider;
29
+ name: string;
30
+ scopes?: CloudConnectionScope[];
31
+ auth_mode?: CloudAuthMode;
32
+ }
33
+ /** Returned when a connection requires customer-side setup (e.g. IAM trust policy) */
34
+ export interface ICloudConnectionSetup {
35
+ connection: ICloudConnection;
36
+ external_id?: string;
37
+ trust_policy?: Record<string, unknown> | string;
38
+ setup_instructions?: string;
39
+ setup_url?: string;
40
+ }
41
+ export interface ICompleteCloudConnectionInput {
42
+ /** AWS cross-account role */
43
+ role_arn?: string;
44
+ /** GCP project */
45
+ project_id?: string;
46
+ /** GCP service account email (optional when using WIF) */
47
+ service_account_email?: string;
48
+ /** Azure */
49
+ tenant_id?: string;
50
+ subscription_id?: string;
51
+ client_id?: string;
52
+ }
53
+ export interface IValidateCloudConnectionResult {
54
+ valid: boolean;
55
+ status: CloudConnectionStatus;
56
+ message?: string;
57
+ tested_at?: string;
58
+ }
59
+ /** Cloud resource kinds exposed by the connector */
60
+ export type CloudResourceService = 's3' | 'sqs' | 'sns' | 'gcs' | 'pubsub' | 'blob' | 'servicebus' | 'rds' | 'neptune' | 'opensearch' | 'pinecone';
61
+ export interface ICloudResource {
62
+ id: string;
63
+ name: string;
64
+ arn?: string;
65
+ region?: string;
66
+ service: CloudResourceService;
67
+ provider: CloudProvider;
68
+ metadata?: Record<string, unknown>;
69
+ }
70
+ export interface IListCloudResourcesInput {
71
+ connectionId: string;
72
+ service: CloudResourceService;
73
+ region?: string;
74
+ prefix?: string;
75
+ page?: number;
76
+ limit?: number;
77
+ }
78
+ export interface IListCloudResourcesResult {
79
+ resources: ICloudResource[];
80
+ total?: number;
81
+ page?: number;
82
+ limit?: number;
83
+ hasMore?: boolean;
84
+ }
85
+ /** Target Ductape component when importing or provisioning */
86
+ export type CloudComponentType = 'storage' | 'messageBrokers' | 'databases' | 'graphs' | 'vectors' | 'caches';
87
+ export interface IImportCloudResourceInput {
88
+ connectionId: string;
89
+ service: CloudResourceService;
90
+ resourceId: string;
91
+ componentType: CloudComponentType;
92
+ productTag: string;
93
+ componentTag: string;
94
+ envSlug: string;
95
+ }
96
+ export interface IProvisionCloudResourceInput {
97
+ connectionId: string;
98
+ service: CloudResourceService;
99
+ template: string;
100
+ componentType: CloudComponentType;
101
+ productTag: string;
102
+ componentTag: string;
103
+ envSlug: string;
104
+ params?: Record<string, unknown>;
105
+ }
106
+ /** Partial product component returned by the connector for builder persistence */
107
+ export interface ICloudComponentDraft {
108
+ componentType: CloudComponentType;
109
+ tag: string;
110
+ name?: string;
111
+ description?: string;
112
+ draft: Record<string, unknown>;
113
+ }
114
+ export interface IImportCloudResourceResult {
115
+ resource: ICloudResource;
116
+ componentDraft: ICloudComponentDraft;
117
+ }
118
+ export interface IProvisionCloudResourceResult extends IImportCloudResourceResult {
119
+ provisioned: boolean;
120
+ }
121
+ /** Runtime short-lived credentials (proxy / connector broker) */
122
+ export interface ICloudRuntimeCredentialsInput {
123
+ connectionId: string;
124
+ productTag: string;
125
+ componentTag: string;
126
+ envSlug: string;
127
+ purpose?: 'runtime' | 'validate';
128
+ }
129
+ export interface ICloudRuntimeCredentials {
130
+ provider: CloudProvider;
131
+ expiresAt: string;
132
+ credentials: Record<string, unknown>;
133
+ }
134
+ /** Optional fields on storage/broker configs when linked via cloud connection */
135
+ export type ComponentCloudAuthMode = 'manual' | 'cloud_connection';
136
+ export interface ICloudLinkedComponentFields {
137
+ authMode?: ComponentCloudAuthMode;
138
+ cloudConnectionId?: string;
139
+ roleArn?: string;
140
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Cloud provider connection and resource types (AWS, GCP, Azure).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=cloud.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.types.js","sourceRoot":"","sources":["../../../src/cloud/types/cloud.types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
@@ -0,0 +1 @@
1
+ export * from './cloud.types';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./cloud.types"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cloud/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B"}
@@ -39,6 +39,20 @@ export interface IDatabaseServiceConfig {
39
39
  private_key: string;
40
40
  /** Optional Redis client for caching */
41
41
  redis_client?: IORedisClient;
42
+ /** Default product tag when omitted from connect/query payloads */
43
+ default_product?: string;
44
+ /** Default environment slug when omitted from connect/query payloads */
45
+ default_env?: string;
46
+ }
47
+ /**
48
+ * Normalized schema snapshot for a database connection context.
49
+ * Used by payload/metadata generation to get full table+column+index context in one call.
50
+ */
51
+ export interface IDatabaseSchemaSnapshot {
52
+ database: string;
53
+ env: string;
54
+ tables: ITableSchema[];
55
+ generatedAt: string;
42
56
  }
43
57
  /**
44
58
  * Main Database Service class
@@ -70,6 +84,7 @@ export declare class DatabaseService {
70
84
  private cacheConfigCache;
71
85
  /** In-flight connect() promises per contextKey to deduplicate concurrent connects and avoid duplicate logs */
72
86
  private connectPromises;
87
+ private runtimeDefaults;
73
88
  /**
74
89
  * Create a new DatabaseService instance
75
90
  * @param config - Optional configuration for authentication and workspace context
@@ -230,6 +245,8 @@ export declare class DatabaseService {
230
245
  * - All parts are automatically capitalized
231
246
  */
232
247
  private generateDbSecretKey;
248
+ private resolveRuntimeProductEnv;
249
+ private mergeConnectionConfig;
233
250
  /**
234
251
  * Connect to a database
235
252
  *
@@ -746,6 +763,19 @@ export declare class DatabaseService {
746
763
  * );
747
764
  */
748
765
  getIndexStatistics(connectionConfig: IConnectionConfig, tableName: string, indexName?: string): Promise<IIndexStatistics[]>;
766
+ /**
767
+ * Get a normalized schema snapshot for the given database/env context.
768
+ *
769
+ * @example
770
+ * const snapshot = await ductape.database.getSchemaSnapshot({
771
+ * env: 'prd',
772
+ * product: 'my-product',
773
+ * database: 'main-db',
774
+ * });
775
+ */
776
+ getSchemaSnapshot(connectionConfig: IConnectionConfig, options?: {
777
+ includeTables?: string[];
778
+ }): Promise<IDatabaseSchemaSnapshot>;
749
779
  /**
750
780
  * Run a migration
751
781
  *
@@ -67,6 +67,7 @@ const logs_service_1 = __importDefault(require("../logs/logs.service"));
67
67
  const logs_types_1 = require("../logs/logs.types");
68
68
  const processor_utils_1 = require("../processor/utils/processor.utils");
69
69
  const secrets_1 = require("../secrets");
70
+ const cloud_runtime_util_1 = require("../cloud/cloud-runtime.util");
70
71
  /** Module-level: last time we logged connect initiated/success/failed per key, to avoid duplicate logs across multiple DatabaseService instances */
71
72
  const lastConnectLogAt = new Map();
72
73
  const CONNECT_LOG_DEBOUNCE_MS = 15000;
@@ -109,11 +110,18 @@ class DatabaseService {
109
110
  this.cacheConfigCache = new Map();
110
111
  /** In-flight connect() promises per contextKey to deduplicate concurrent connects and avoid duplicate logs */
111
112
  this.connectPromises = new Map();
113
+ this.runtimeDefaults = {};
112
114
  this.config = config || null;
113
115
  this.adapterFactory = new adapter_factory_1.AdapterFactory();
114
116
  this.transactionManager = new transaction_manager_1.TransactionManager();
115
117
  this.actionManager = new action_manager_1.ActionManager(this);
116
118
  this._privateKey = (config === null || config === void 0 ? void 0 : config.private_key) || '';
119
+ if ((config === null || config === void 0 ? void 0 : config.default_product) || (config === null || config === void 0 ? void 0 : config.default_env)) {
120
+ this.runtimeDefaults = {
121
+ default_product: config.default_product,
122
+ default_env: config.default_env,
123
+ };
124
+ }
117
125
  // Initialize CacheManager (Redis is optional - Tier 1 internal cache and Tier 3 remote cache always work)
118
126
  if ((config === null || config === void 0 ? void 0 : config.workspace_id) && (config === null || config === void 0 ? void 0 : config.public_key) && (config === null || config === void 0 ? void 0 : config.user_id) && (config === null || config === void 0 ? void 0 : config.token)) {
119
127
  this.cacheManager = new cache_manager_1.CacheManager({
@@ -563,6 +571,8 @@ class DatabaseService {
563
571
  connected: false,
564
572
  name: config.name,
565
573
  description: config.description,
574
+ authMode: envConfig.authMode,
575
+ cloudConnectionId: envConfig.cloudConnectionId,
566
576
  });
567
577
  }
568
578
  }
@@ -594,6 +604,20 @@ class DatabaseService {
594
604
  }
595
605
  return `DB_${sanitize(productKey)}_${sanitize(assetTag)}_${sanitize(env)}_URL`;
596
606
  }
607
+ resolveRuntimeProductEnv(fields) {
608
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
609
+ return {
610
+ product: (_d = (_c = (_a = fields.product) !== null && _a !== void 0 ? _a : (_b = this.currentContext) === null || _b === void 0 ? void 0 : _b.product) !== null && _c !== void 0 ? _c : this.runtimeDefaults.default_product) !== null && _d !== void 0 ? _d : (_e = this.config) === null || _e === void 0 ? void 0 : _e.default_product,
611
+ env: (_j = (_h = (_f = fields.env) !== null && _f !== void 0 ? _f : (_g = this.currentContext) === null || _g === void 0 ? void 0 : _g.env) !== null && _h !== void 0 ? _h : this.runtimeDefaults.default_env) !== null && _j !== void 0 ? _j : (_k = this.config) === null || _k === void 0 ? void 0 : _k.default_env,
612
+ };
613
+ }
614
+ mergeConnectionConfig(config) {
615
+ const { product, env } = this.resolveRuntimeProductEnv(config);
616
+ if (!(product === null || product === void 0 ? void 0 : product.trim()) || !(env === null || env === void 0 ? void 0 : env.trim())) {
617
+ throw new database_error_1.DatabaseError('product and env are required. Pass them in connect() or set both on the Ductape constructor.', enums_1.DatabaseErrorType.VALIDATION_ERROR);
618
+ }
619
+ return Object.assign(Object.assign({}, config), { product: product.trim(), env: env.trim() });
620
+ }
597
621
  /**
598
622
  * Connect to a database
599
623
  *
@@ -613,6 +637,7 @@ class DatabaseService {
613
637
  */
614
638
  async connect(config) {
615
639
  var _a, _b, _c;
640
+ config = this.mergeConnectionConfig(config);
616
641
  const process_id = (0, processor_utils_1.generateObjectId)();
617
642
  const start = Date.now();
618
643
  const contextKey = this.buildContextKey(config.database, config.env);
@@ -669,6 +694,8 @@ class DatabaseService {
669
694
  slug: e.slug,
670
695
  connection_url: e.connection_url,
671
696
  description: e.description,
697
+ authMode: e.authMode,
698
+ cloudConnectionId: e.cloudConnectionId,
672
699
  })),
673
700
  });
674
701
  adapter = this.adapters.get(contextKey);
@@ -754,6 +781,8 @@ class DatabaseService {
754
781
  slug: e.slug,
755
782
  connection_url: e.connection_url,
756
783
  description: e.description,
784
+ authMode: e.authMode,
785
+ cloudConnectionId: e.cloudConnectionId,
757
786
  })),
758
787
  });
759
788
  adapter = this.adapters.get(contextKey);
@@ -801,17 +830,38 @@ class DatabaseService {
801
830
  this.logService.add(Object.assign(Object.assign({}, baseLogs), { start, message: 'Database connect - initiated', status: logs_types_1.LogEventStatus.PROCESSING }));
802
831
  }
803
832
  try {
804
- // Resolve secret reference in connection URL if needed
805
833
  let connectionUrl = context.connectionUrl;
806
- const secretCheck = (0, secrets_1.isSecretReference)(connectionUrl);
807
- if (secretCheck.isSecret) {
808
- const secretsService = (0, secrets_1.getSecretsService)();
809
- if (secretsService) {
810
- const resolved = await secretsService.resolve(connectionUrl, { env: config.env });
811
- connectionUrl = resolved.value;
812
- }
813
- else {
814
- throw new database_error_1.DatabaseError(`Connection URL contains secret reference but secrets service is not initialized.`, enums_1.DatabaseErrorType.CONNECTION_ERROR);
834
+ if (this.config && (context.authMode === 'cloud_connection' || (0, secrets_1.isSecretReference)(connectionUrl).isSecret)) {
835
+ const resolvedEnv = await (0, cloud_runtime_util_1.resolveCloudLinkedEnvConfig)({
836
+ connection_url: context.connectionUrl,
837
+ authMode: context.authMode,
838
+ cloudConnectionId: context.cloudConnectionId,
839
+ }, {
840
+ environment: this.config.env_type,
841
+ auth: {
842
+ token: this.config.token,
843
+ public_key: this.config.public_key,
844
+ user_id: this.config.user_id,
845
+ workspace_id: this.config.workspace_id,
846
+ access_key: this.config.access_key,
847
+ },
848
+ productTag: config.product || '',
849
+ componentTag: config.database,
850
+ envSlug: config.env,
851
+ });
852
+ connectionUrl = String(resolvedEnv.connection_url || connectionUrl);
853
+ }
854
+ else {
855
+ const secretCheck = (0, secrets_1.isSecretReference)(connectionUrl);
856
+ if (secretCheck.isSecret) {
857
+ const secretsService = (0, secrets_1.getSecretsService)();
858
+ if (secretsService) {
859
+ const resolved = await secretsService.resolve(connectionUrl, { env: config.env });
860
+ connectionUrl = resolved.value;
861
+ }
862
+ else {
863
+ throw new database_error_1.DatabaseError(`Connection URL contains secret reference but secrets service is not initialized.`, enums_1.DatabaseErrorType.CONNECTION_ERROR);
864
+ }
815
865
  }
816
866
  }
817
867
  await adapter.connect({
@@ -1977,6 +2027,32 @@ class DatabaseService {
1977
2027
  const adapter = this.getAdapter(connectionConfig);
1978
2028
  return adapter.getIndexStatistics(tableName, indexName);
1979
2029
  }
2030
+ /**
2031
+ * Get a normalized schema snapshot for the given database/env context.
2032
+ *
2033
+ * @example
2034
+ * const snapshot = await ductape.database.getSchemaSnapshot({
2035
+ * env: 'prd',
2036
+ * product: 'my-product',
2037
+ * database: 'main-db',
2038
+ * });
2039
+ */
2040
+ async getSchemaSnapshot(connectionConfig, options) {
2041
+ var _a;
2042
+ await this.ensureAdapterFor(connectionConfig);
2043
+ const adapter = this.getAdapter(connectionConfig);
2044
+ const tableNames = ((_a = options === null || options === void 0 ? void 0 : options.includeTables) === null || _a === void 0 ? void 0 : _a.length) ? options.includeTables : await adapter.listTables();
2045
+ const tables = [];
2046
+ for (const tableName of tableNames) {
2047
+ tables.push(await adapter.getTableSchema(tableName));
2048
+ }
2049
+ return {
2050
+ database: connectionConfig.database,
2051
+ env: connectionConfig.env,
2052
+ tables,
2053
+ generatedAt: new Date().toISOString(),
2054
+ };
2055
+ }
1980
2056
  // ==================== MIGRATION OPERATIONS ====================
1981
2057
  /**
1982
2058
  * Run a migration