@deepnote/database-integrations 1.0.0

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/index.cjs ADDED
@@ -0,0 +1,734 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ let build_url_ts = require("build-url-ts");
25
+ build_url_ts = __toESM(build_url_ts);
26
+ let zod = require("zod");
27
+ zod = __toESM(zod);
28
+
29
+ //#region src/sql-integration-auth-methods.ts
30
+ const AwsAuthMethods = {
31
+ AccessKeys: "access-keys",
32
+ IamRole: "iam-role"
33
+ };
34
+ const SnowflakeAuthMethods = {
35
+ AzureAd: "azure",
36
+ KeyPair: "key-pair",
37
+ ServiceAccountKeyPair: "service-account-key-pair",
38
+ NativeSnowflake: "snowflake",
39
+ Okta: "okta",
40
+ Password: "password"
41
+ };
42
+ const BigQueryAuthMethods = {
43
+ ServiceAccount: "service-account",
44
+ GoogleOauth: "google-oauth"
45
+ };
46
+ const DatabaseAuthMethods = {
47
+ UsernameAndPassword: "username-and-password",
48
+ IndividualCredentials: "individual-credentials"
49
+ };
50
+ const federatedAuthMethods = [
51
+ SnowflakeAuthMethods.Okta,
52
+ SnowflakeAuthMethods.NativeSnowflake,
53
+ SnowflakeAuthMethods.AzureAd,
54
+ SnowflakeAuthMethods.KeyPair,
55
+ BigQueryAuthMethods.GoogleOauth,
56
+ DatabaseAuthMethods.IndividualCredentials
57
+ ];
58
+ function isFederatedAuthMethod(authMethod) {
59
+ return federatedAuthMethods.includes(authMethod);
60
+ }
61
+ function isFederatedAuthMetadata(metadata) {
62
+ return isFederatedAuthMethod(metadata.authMethod);
63
+ }
64
+
65
+ //#endregion
66
+ //#region src/snowflake-integration-env-vars.ts
67
+ function getSnowflakeSqlAlchemyInput(metadata, params) {
68
+ if (isFederatedAuthMetadata(metadata)) return null;
69
+ const { username, accountName, database, authMethod } = metadata;
70
+ if (authMethod === SnowflakeAuthMethods.ServiceAccountKeyPair) {
71
+ const url$1 = (0, build_url_ts.default)(`snowflake://${encodeURIComponent(username)}@${encodeURIComponent(accountName)}`, {
72
+ path: database,
73
+ queryParams: {
74
+ ...createBaseQueryParams(metadata, params.snowflakePartnerIdentifier),
75
+ authenticator: "snowflake_jwt"
76
+ }
77
+ });
78
+ if (!url$1) throw new Error("getSnowflakeEnvVar URL must be defined");
79
+ return createSqlAlchemyInputFromUrl(url$1, {
80
+ privateKey: metadata.privateKey,
81
+ password: metadata.privateKeyPassphrase,
82
+ username: metadata.username
83
+ });
84
+ }
85
+ const url = (0, build_url_ts.default)(`snowflake://${encodeURIComponent(username)}:${encodeURIComponent(metadata.password)}@${encodeURIComponent(accountName)}`, {
86
+ path: database,
87
+ queryParams: { ...createBaseQueryParams(metadata, params.snowflakePartnerIdentifier) }
88
+ });
89
+ if (!url) throw new Error("getSnowflakeEnvVar URL must be defined");
90
+ return createSqlAlchemyInputFromUrl(url);
91
+ }
92
+ function createBaseQueryParams(metadata, snowflakePartnerIdentifier) {
93
+ return {
94
+ warehouse: metadata.warehouse,
95
+ role: metadata.role,
96
+ application: snowflakePartnerIdentifier
97
+ };
98
+ }
99
+ function createSqlAlchemyInputFromUrl(url, keyPair) {
100
+ return {
101
+ url,
102
+ params: keyPair ? {
103
+ snowflake_private_key: Buffer.from(keyPair.privateKey).toString("base64"),
104
+ snowflake_private_key_passphrase: keyPair.password || void 0
105
+ } : {},
106
+ param_style: "pyformat"
107
+ };
108
+ }
109
+
110
+ //#endregion
111
+ //#region src/database-integration-env-vars.ts
112
+ function getIntegrationListEnv(sqlIntegrations, params) {
113
+ const envVars = [];
114
+ const errors = [];
115
+ sqlIntegrations.forEach((integration) => {
116
+ const namePrefix = convertToEnvironmentVariableName(integration.name);
117
+ const envVarsForThisIntegration = Object.entries(integration.metadata).map(([key, rawValue]) => {
118
+ const name = `${namePrefix}_${key.toUpperCase()}`;
119
+ const value = String(rawValue);
120
+ if (integration.type === "mongodb" && integration.metadata.sslEnabled && key === "connection_string") return {
121
+ name,
122
+ value: addSslOptionsToMongoConnectionString(params.projectRootDirectory, value, integration.id, integration.metadata)
123
+ };
124
+ return {
125
+ name,
126
+ value
127
+ };
128
+ });
129
+ if (integration.type !== "mongodb") try {
130
+ const envVar = getEnvVarForSqlCells(integration, params);
131
+ if (envVar) envVarsForThisIntegration.push(envVar);
132
+ } catch (error) {
133
+ errors.push(error);
134
+ }
135
+ envVars.push(...envVarsForThisIntegration.filter((envVar) => !!envVar.name));
136
+ });
137
+ return {
138
+ envVars,
139
+ errors
140
+ };
141
+ }
142
+ const duckDbEnvVar = {
143
+ url: `deepnote+duckdb:///:memory:`,
144
+ params: {},
145
+ param_style: "qmark"
146
+ };
147
+ function addSslOptionsToMongoConnectionString(projectRoot, connectionString, integrationId, metadata) {
148
+ const [base, paramString] = connectionString.split("?");
149
+ const params = new URLSearchParams(paramString);
150
+ params.set("tls", "true");
151
+ if (metadata.caCertificateName) {
152
+ const path = getCACertificatePath({
153
+ projectRoot,
154
+ integrationId,
155
+ caCertificateName: metadata.caCertificateName
156
+ });
157
+ params.set("tlsCAFile", path);
158
+ }
159
+ return `${base}?${params.toString()}`;
160
+ }
161
+ function getEnvVarForSqlCells(integration, params) {
162
+ const sqlAlchemyInput = getSqlAlchemyInput(integration, params);
163
+ if (!sqlAlchemyInput) return null;
164
+ return {
165
+ name: convertToEnvironmentVariableName(getSqlEnvVarName(integration.id)),
166
+ value: JSON.stringify({
167
+ integration_id: integration.id,
168
+ ...sqlAlchemyInput
169
+ })
170
+ };
171
+ }
172
+ /**
173
+ * @returns sql alchemy input, or undefined if there is an error.
174
+ *
175
+ * The URL and the params are passed to SQL Alchemy's create_engine function as arguments. The params are
176
+ * passed as keyword arguments to the function.
177
+ * https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine
178
+ *
179
+ * See the `query_data_source` method in Deepnote Toolkit for more details:
180
+ * https://github.com/deepnote/deepnote-toolkit/blob/main/deepnote_toolkit/sql/sql_execution.py#L321
181
+ */
182
+ function getSqlAlchemyInput(integration, params) {
183
+ if (integration.federated_auth_method) return null;
184
+ switch (integration.type) {
185
+ case "alloydb":
186
+ case "pgsql": return getPostgresSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
187
+ case "athena": return getAthenaSqlAlchemyInput(integration.metadata);
188
+ case "big-query": return getBigQuerySqlAlchemyInput(integration.metadata);
189
+ case "clickhouse": return getClickHouseSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
190
+ case "databricks": return getDatabricksSqlAlchemyInput(integration.metadata);
191
+ case "dremio": return getDremioSqlAlchemyInput(integration.metadata);
192
+ case "mariadb":
193
+ case "mindsdb":
194
+ case "mysql": return getMySqlSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
195
+ case "materialize": return getMaterializePostgresSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
196
+ case "pandas-dataframe": return { ...duckDbEnvVar };
197
+ case "redshift": return getRedshiftSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
198
+ case "snowflake": return getSnowflakeSqlAlchemyInput(integration.metadata, { snowflakePartnerIdentifier: params.snowflakePartnerIdentifier });
199
+ case "spanner": return getSpannerSqlAlchemyInput(integration.metadata);
200
+ case "sql-server": return getSQLServerVar(integration.metadata);
201
+ case "trino": return getTrinoEnvVars(integration.id, integration.metadata, params.projectRootDirectory);
202
+ default: assertNever(integration);
203
+ }
204
+ }
205
+ const getDatabricksSqlAlchemyInput = ({ httpPath, host, token, port, schema, catalog, sshEnabled, sshHost, sshPort, sshUser }) => {
206
+ return {
207
+ url: `databricks+connector://token:${encodeURIComponent(token)}@${host}:${port}`,
208
+ params: { connect_args: {
209
+ http_path: httpPath,
210
+ schema,
211
+ catalog
212
+ } },
213
+ param_style: "pyformat",
214
+ ssh_options: {
215
+ enabled: String(sshEnabled),
216
+ host: sshHost,
217
+ port: sshPort,
218
+ user: sshUser
219
+ }
220
+ };
221
+ };
222
+ const getDremioSqlAlchemyInput = ({ port, host, token, schema, sshEnabled, sshHost, sshPort, sshUser }) => {
223
+ const url = new URL(`dremio+flight://${host}:${port}${schema ? "/" + schema : ""}`);
224
+ url.searchParams.set("UseEncryption", "true");
225
+ url.searchParams.set("Token", token);
226
+ return {
227
+ url: url.href,
228
+ params: {},
229
+ param_style: "pyformat",
230
+ ssh_options: {
231
+ enabled: String(sshEnabled),
232
+ host: sshHost,
233
+ port: sshPort,
234
+ user: sshUser
235
+ }
236
+ };
237
+ };
238
+ const getSQLServerVar = ({ user, password, host, port, database, sshEnabled, sshHost, sshPort, sshUser }) => {
239
+ const portSuffix = port ? `:${port}` : "";
240
+ return {
241
+ url: `mssql+pymssql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}${portSuffix}/${database}`,
242
+ params: {},
243
+ param_style: "pyformat",
244
+ ssh_options: {
245
+ enabled: String(sshEnabled),
246
+ host: sshHost,
247
+ port: sshPort,
248
+ user: sshUser
249
+ }
250
+ };
251
+ };
252
+ const getPostgresSqlAlchemyInput = (integrationId, projectRootDirectory, { user, password, host, port, database, sshEnabled, sshHost, sshPort, sshUser, sslEnabled, caCertificateName }) => {
253
+ const portSuffix = port ? `:${port}` : "";
254
+ const mode = getPostgresStyleMode(caCertificateName, sslEnabled);
255
+ return {
256
+ url: `postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}${portSuffix}/${database}`,
257
+ params: { connect_args: {
258
+ keepalives: 1,
259
+ keepalives_idle: 30,
260
+ keepalives_interval: 10,
261
+ keepalives_count: 5,
262
+ sslmode: mode,
263
+ sslrootcert: caCertificateName ? getCACertificatePath({
264
+ projectRoot: projectRootDirectory,
265
+ integrationId,
266
+ caCertificateName
267
+ }) : void 0
268
+ } },
269
+ param_style: "pyformat",
270
+ ssh_options: {
271
+ enabled: String(sshEnabled),
272
+ host: sshHost,
273
+ port: sshPort,
274
+ user: sshUser
275
+ }
276
+ };
277
+ };
278
+ const getRedshiftSqlAlchemyInput = (integrationId, projectRootDirectory, metadata) => {
279
+ if (isFederatedAuthMethod(metadata.authMethod)) return null;
280
+ const portSuffix = metadata.port ? `:${metadata.port}` : "";
281
+ const mode = getPostgresStyleMode(metadata.caCertificateName, metadata.sslEnabled);
282
+ const credentials = metadata.authMethod === DatabaseAuthMethods.UsernameAndPassword ? `${encodeURIComponent(metadata.user)}:${encodeURIComponent(metadata.password)}` : "";
283
+ const vars = {
284
+ url: `redshift+psycopg2://${credentials ? `${credentials}@` : ""}${metadata.host}${portSuffix}/${metadata.database}`,
285
+ params: { connect_args: {
286
+ keepalives: 1,
287
+ keepalives_idle: 30,
288
+ keepalives_interval: 10,
289
+ keepalives_count: 5,
290
+ sslmode: mode,
291
+ sslrootcert: metadata.caCertificateName ? getCACertificatePath({
292
+ projectRoot: projectRootDirectory,
293
+ integrationId,
294
+ caCertificateName: metadata.caCertificateName
295
+ }) : void 0
296
+ } },
297
+ param_style: "pyformat",
298
+ ssh_options: {
299
+ enabled: String(metadata.sshEnabled),
300
+ host: metadata.sshHost,
301
+ port: metadata.sshPort,
302
+ user: metadata.sshUser
303
+ }
304
+ };
305
+ if (metadata.authMethod === AwsAuthMethods.IamRole && metadata.roleArn && metadata.roleExternalId) vars.iamParams = {
306
+ integrationId,
307
+ type: "redshift"
308
+ };
309
+ return vars;
310
+ };
311
+ function getPostgresStyleMode(caCertificateName, sslEnabled) {
312
+ if (caCertificateName) return "verify-ca";
313
+ if (sslEnabled) return "require";
314
+ return "prefer";
315
+ }
316
+ const getMaterializePostgresSqlAlchemyInput = (integrationId, projectRootDirectory, { user, password, host, port, database, sshEnabled, sshHost, sshPort, sshUser, sslEnabled, caCertificateName, cluster }) => {
317
+ const portSuffix = port ? `:${port}` : "";
318
+ const mode = getPostgresStyleMode(caCertificateName, sslEnabled);
319
+ return {
320
+ url: `postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}${portSuffix}/${database}?options=--cluster%3D${cluster}`,
321
+ params: { connect_args: {
322
+ sslmode: mode,
323
+ sslrootcert: caCertificateName ? getCACertificatePath({
324
+ projectRoot: projectRootDirectory,
325
+ integrationId,
326
+ caCertificateName
327
+ }) : void 0
328
+ } },
329
+ param_style: "pyformat",
330
+ ssh_options: {
331
+ enabled: String(sshEnabled),
332
+ host: sshHost,
333
+ port: sshPort,
334
+ user: sshUser
335
+ }
336
+ };
337
+ };
338
+ const getTrinoEnvVars = (integrationId, metadata, projectRootDirectory) => {
339
+ return {
340
+ url: `trino://${encodeURIComponent(metadata.user)}:${encodeURIComponent(metadata.password)}@${metadata.host}:${metadata.port}/${encodeURIComponent(metadata.database)}`,
341
+ params: { connect_args: {
342
+ ...metadata.sslEnabled ? { http_scheme: "https" } : {},
343
+ ...metadata.caCertificateName ? { verify: getCACertificatePath({
344
+ projectRoot: projectRootDirectory,
345
+ integrationId,
346
+ caCertificateName: metadata.caCertificateName
347
+ }) } : {}
348
+ } },
349
+ param_style: "pyformat"
350
+ };
351
+ };
352
+ const getAthenaSqlAlchemyInput = ({ access_key_id, region, s3_output_path, secret_access_key, workgroup }) => {
353
+ const baseUrl = `awsathena+rest://${encodeURIComponent(access_key_id)}:${encodeURIComponent(secret_access_key)}@athena.${region}.amazonaws.com:443/`;
354
+ const params = new URLSearchParams();
355
+ params.set("s3_staging_dir", s3_output_path);
356
+ if (workgroup) params.set("work_group", workgroup);
357
+ return {
358
+ url: `${baseUrl}?${params.toString()}`,
359
+ params: {},
360
+ param_style: "pyformat"
361
+ };
362
+ };
363
+ const getClickHouseSqlAlchemyInput = (integrationId, projectRootDirectory, { user, password, host, port, database, sshEnabled, sshHost, sshPort, sshUser, sslEnabled, caCertificateName }) => {
364
+ const portSuffix = port ? `:${port}` : "";
365
+ const params = new URLSearchParams();
366
+ params.set("protocol", "https");
367
+ if (sslEnabled) {
368
+ params.set("secure", "true");
369
+ params.set("tls_mode", "strict");
370
+ }
371
+ if (caCertificateName) {
372
+ const certificatePath = getCACertificatePath({
373
+ projectRoot: projectRootDirectory,
374
+ integrationId,
375
+ caCertificateName
376
+ });
377
+ params.set("verify", certificatePath);
378
+ }
379
+ return {
380
+ url: `clickhouse://${password ? `${encodeURIComponent(user)}:${encodeURIComponent(password)}` : encodeURIComponent(user)}@${host}${portSuffix}/${database}?${params.toString()}`,
381
+ params: {},
382
+ param_style: "pyformat",
383
+ ssh_options: {
384
+ enabled: String(sshEnabled),
385
+ host: sshHost,
386
+ port: sshPort,
387
+ user: sshUser
388
+ }
389
+ };
390
+ };
391
+ var BigQueryServiceAccountParseError = class extends Error {
392
+ cause;
393
+ constructor(message, params) {
394
+ super(message);
395
+ this.name = "BigQueryServiceAccountParseError";
396
+ this.cause = params.cause;
397
+ }
398
+ };
399
+ const getBigQuerySqlAlchemyInput = (metadata) => {
400
+ if (isFederatedAuthMetadata(metadata)) return null;
401
+ try {
402
+ return {
403
+ url: "bigquery://",
404
+ params: { credentials_info: JSON.parse(metadata.service_account) },
405
+ param_style: "pyformat"
406
+ };
407
+ } catch (error) {
408
+ throw new BigQueryServiceAccountParseError("Failed to parse bigquery service account, returning empty environment variable.", { cause: error instanceof Error ? error : new Error(String(error)) });
409
+ }
410
+ };
411
+ var SpannerServiceAccountParseError = class extends Error {
412
+ cause;
413
+ constructor(message, params) {
414
+ super(message);
415
+ this.name = "SpannerServiceAccountParseError";
416
+ this.cause = params.cause;
417
+ }
418
+ };
419
+ const getSpannerSqlAlchemyInput = (metadata) => {
420
+ try {
421
+ const projectId = JSON.parse(metadata.service_account).project_id;
422
+ if (!projectId || typeof projectId !== "string") throw new SpannerServiceAccountParseError("Failed to parse spanner service account, returning empty environment variable.", { cause: /* @__PURE__ */ new Error("project_id is missing in service account") });
423
+ return {
424
+ url: `spanner+spanner:///projects/${projectId}/instances/${metadata.instance}/databases/${metadata.database}`,
425
+ params: {},
426
+ param_style: "pyformat"
427
+ };
428
+ } catch (error) {
429
+ if (error instanceof SpannerServiceAccountParseError) throw error;
430
+ throw new SpannerServiceAccountParseError("Failed to parse spanner service account, returning empty environment variable.", { cause: error instanceof Error ? error : new Error(String(error)) });
431
+ }
432
+ };
433
+ const getMySqlSqlAlchemyInput = (integrationId, projectRootDirectory, { user, password, host, port, database, sshEnabled, sshHost, sshPort, sshUser, caCertificateName }) => {
434
+ const portSuffix = port ? `:${port}` : "";
435
+ let ssl;
436
+ if (caCertificateName) ssl = {
437
+ ca: getCACertificatePath({
438
+ projectRoot: projectRootDirectory,
439
+ integrationId,
440
+ caCertificateName
441
+ }),
442
+ check_hostname: false
443
+ };
444
+ else ssl = { enable: true };
445
+ return {
446
+ url: `mysql+pymysql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}${portSuffix}/${database}`,
447
+ params: { connect_args: { ssl } },
448
+ param_style: "pyformat",
449
+ ssh_options: {
450
+ enabled: String(sshEnabled),
451
+ host: sshHost,
452
+ port: sshPort,
453
+ user: sshUser
454
+ }
455
+ };
456
+ };
457
+ function getCACertificatePath({ projectRoot, integrationId, caCertificateName }) {
458
+ return `${projectRoot ?? ""}/.deepnote/${integrationId}/${caCertificateName}`;
459
+ }
460
+ function convertToEnvironmentVariableName(str) {
461
+ return (/^\d/.test(str) ? `_${str}` : str).toUpperCase().replace(/[^\w]/g, "_");
462
+ }
463
+ function getSqlEnvVarName(integrationId) {
464
+ return `SQL_${integrationId}`;
465
+ }
466
+ function assertNever(value) {
467
+ throw new Error(`Unexpected value: ${value}`);
468
+ }
469
+
470
+ //#endregion
471
+ //#region src/database-integration-metadata-schemas.ts
472
+ const athenaMetadataSchema = zod.z.object({
473
+ access_key_id: zod.z.string(),
474
+ region: zod.z.string(),
475
+ s3_output_path: zod.z.string(),
476
+ secret_access_key: zod.z.string(),
477
+ workgroup: zod.z.string().optional()
478
+ });
479
+ const bigqueryMetadataSchema = zod.z.discriminatedUnion("authMethod", [zod.z.object({
480
+ authMethod: zod.z.literal(BigQueryAuthMethods.ServiceAccount),
481
+ service_account: zod.z.string()
482
+ }), zod.z.object({
483
+ authMethod: zod.z.literal(BigQueryAuthMethods.GoogleOauth),
484
+ project: zod.z.string(),
485
+ clientId: zod.z.string(),
486
+ clientSecret: zod.z.string()
487
+ })]);
488
+ const clickhouseMetadataSchema = zod.z.object({
489
+ host: zod.z.string(),
490
+ user: zod.z.string(),
491
+ password: zod.z.string().optional(),
492
+ database: zod.z.string(),
493
+ port: zod.z.string().optional(),
494
+ sshEnabled: zod.z.boolean().optional(),
495
+ sshHost: zod.z.string().optional(),
496
+ sshPort: zod.z.string().optional(),
497
+ sshUser: zod.z.string().optional(),
498
+ sslEnabled: zod.z.boolean().optional(),
499
+ caCertificateName: zod.z.string().optional(),
500
+ caCertificateText: zod.z.string().optional()
501
+ });
502
+ const databricksMetadataSchema = zod.z.object({
503
+ host: zod.z.string(),
504
+ httpPath: zod.z.string(),
505
+ token: zod.z.string(),
506
+ port: zod.z.string(),
507
+ schema: zod.z.string().optional(),
508
+ catalog: zod.z.string().optional(),
509
+ sshEnabled: zod.z.boolean().optional(),
510
+ sshHost: zod.z.string().optional(),
511
+ sshPort: zod.z.string().optional(),
512
+ sshUser: zod.z.string().optional()
513
+ });
514
+ const dremioMetadataSchema = zod.z.object({
515
+ schema: zod.z.string(),
516
+ host: zod.z.string(),
517
+ port: zod.z.string(),
518
+ token: zod.z.string(),
519
+ sshEnabled: zod.z.boolean().optional(),
520
+ sshHost: zod.z.string().optional(),
521
+ sshPort: zod.z.string().optional(),
522
+ sshUser: zod.z.string().optional()
523
+ });
524
+ const mongodbMetadataSchema = zod.z.object({
525
+ connection_string: zod.z.string(),
526
+ rawConnectionString: zod.z.string().optional(),
527
+ prefix: zod.z.string().optional(),
528
+ host: zod.z.string().optional(),
529
+ port: zod.z.string().optional(),
530
+ user: zod.z.string().optional(),
531
+ password: zod.z.string().optional(),
532
+ database: zod.z.string().optional(),
533
+ options: zod.z.string().optional(),
534
+ sshEnabled: zod.z.boolean().optional(),
535
+ sshHost: zod.z.string().optional(),
536
+ sshPort: zod.z.string().optional(),
537
+ sshUser: zod.z.string().optional(),
538
+ sslEnabled: zod.z.boolean().optional(),
539
+ caCertificateName: zod.z.string().optional(),
540
+ caCertificateText: zod.z.string().optional()
541
+ });
542
+ const pandasDataframeMetadataSchema = zod.z.object({});
543
+ const commonRedshiftMetadataSchema = zod.z.object({
544
+ database: zod.z.string(),
545
+ host: zod.z.string(),
546
+ port: zod.z.string().optional(),
547
+ sshEnabled: zod.z.boolean().optional(),
548
+ sshHost: zod.z.string().optional(),
549
+ sshPort: zod.z.string().optional(),
550
+ sshUser: zod.z.string().optional(),
551
+ sslEnabled: zod.z.boolean().optional(),
552
+ caCertificateName: zod.z.string().optional(),
553
+ caCertificateText: zod.z.string().optional()
554
+ });
555
+ const redshiftMetadataSchema = zod.z.discriminatedUnion("authMethod", [
556
+ commonRedshiftMetadataSchema.extend({
557
+ authMethod: zod.z.literal(DatabaseAuthMethods.UsernameAndPassword),
558
+ user: zod.z.string(),
559
+ password: zod.z.string()
560
+ }),
561
+ commonRedshiftMetadataSchema.extend({
562
+ authMethod: zod.z.literal(AwsAuthMethods.IamRole),
563
+ roleArn: zod.z.string(),
564
+ roleExternalId: zod.z.string(),
565
+ roleNonce: zod.z.string()
566
+ }),
567
+ commonRedshiftMetadataSchema.extend({ authMethod: zod.z.literal(DatabaseAuthMethods.IndividualCredentials) })
568
+ ]);
569
+ const commonSnowflakeMetadataSchema = zod.z.object({
570
+ accountName: zod.z.string(),
571
+ warehouse: zod.z.string().optional(),
572
+ database: zod.z.string().optional(),
573
+ role: zod.z.string().optional()
574
+ });
575
+ const snowflakeMetadataSchema = zod.z.discriminatedUnion("authMethod", [
576
+ commonSnowflakeMetadataSchema.extend({
577
+ authMethod: zod.z.literal(SnowflakeAuthMethods.Password),
578
+ username: zod.z.string(),
579
+ password: zod.z.string()
580
+ }),
581
+ commonSnowflakeMetadataSchema.extend({
582
+ authMethod: zod.z.literal(SnowflakeAuthMethods.Okta),
583
+ clientId: zod.z.string(),
584
+ clientSecret: zod.z.string(),
585
+ oktaSubdomain: zod.z.string(),
586
+ identityProvider: zod.z.string(),
587
+ authorizationServer: zod.z.string()
588
+ }),
589
+ commonSnowflakeMetadataSchema.extend({
590
+ authMethod: zod.z.literal(SnowflakeAuthMethods.NativeSnowflake),
591
+ clientId: zod.z.string(),
592
+ clientSecret: zod.z.string()
593
+ }),
594
+ commonSnowflakeMetadataSchema.extend({
595
+ authMethod: zod.z.literal(SnowflakeAuthMethods.AzureAd),
596
+ clientId: zod.z.string(),
597
+ clientSecret: zod.z.string(),
598
+ resource: zod.z.string(),
599
+ tenant: zod.z.string()
600
+ }),
601
+ commonSnowflakeMetadataSchema.extend({ authMethod: zod.z.literal(SnowflakeAuthMethods.KeyPair) }),
602
+ commonSnowflakeMetadataSchema.extend({
603
+ authMethod: zod.z.literal(SnowflakeAuthMethods.ServiceAccountKeyPair),
604
+ username: zod.z.string(),
605
+ privateKey: zod.z.string(),
606
+ privateKeyPassphrase: zod.z.string().optional()
607
+ })
608
+ ]);
609
+ const spannerMetadataSchema = zod.z.object({
610
+ service_account: zod.z.string(),
611
+ dataBoostEnabled: zod.z.boolean(),
612
+ instance: zod.z.string(),
613
+ database: zod.z.string()
614
+ });
615
+ const trinoMetadataSchema = zod.z.object({
616
+ host: zod.z.string(),
617
+ user: zod.z.string(),
618
+ password: zod.z.string(),
619
+ database: zod.z.string(),
620
+ port: zod.z.string(),
621
+ sshEnabled: zod.z.boolean().optional(),
622
+ sshHost: zod.z.string().optional(),
623
+ sshPort: zod.z.string().optional(),
624
+ sshUser: zod.z.string().optional(),
625
+ sslEnabled: zod.z.boolean().optional(),
626
+ caCertificateName: zod.z.string().optional(),
627
+ caCertificateText: zod.z.string().optional()
628
+ });
629
+ const commonDatabaseSchema = zod.z.object({
630
+ host: zod.z.string(),
631
+ user: zod.z.string(),
632
+ password: zod.z.string(),
633
+ database: zod.z.string(),
634
+ sshEnabled: zod.z.boolean().optional(),
635
+ sshHost: zod.z.string().optional(),
636
+ sshPort: zod.z.string().optional(),
637
+ sshUser: zod.z.string().optional()
638
+ });
639
+ const alloydbMetadataSchema = commonDatabaseSchema.extend({
640
+ port: zod.z.string().optional(),
641
+ sslEnabled: zod.z.boolean().optional(),
642
+ caCertificateName: zod.z.string().optional(),
643
+ caCertificateText: zod.z.string().optional()
644
+ });
645
+ const mariadbMetadataSchema = commonDatabaseSchema.extend({
646
+ port: zod.z.string().optional(),
647
+ caCertificateName: zod.z.string().optional()
648
+ });
649
+ const mindsdbMetadataSchema = commonDatabaseSchema.extend({
650
+ port: zod.z.string().optional(),
651
+ caCertificateName: zod.z.string().optional()
652
+ });
653
+ const mysqlMetadataSchema = commonDatabaseSchema.extend({
654
+ port: zod.z.string().optional(),
655
+ caCertificateName: zod.z.string().optional()
656
+ });
657
+ const pgsqlMetadataSchema = commonDatabaseSchema.extend({
658
+ port: zod.z.string().optional(),
659
+ sslEnabled: zod.z.boolean().optional(),
660
+ caCertificateName: zod.z.string().optional(),
661
+ caCertificateText: zod.z.string().optional()
662
+ });
663
+ const materializeMetadataSchema = pgsqlMetadataSchema.extend({ cluster: zod.z.string() });
664
+ const sqlServerMetadataSchema = commonDatabaseSchema.extend({ port: zod.z.string() });
665
+ const databaseMetadataSchemasByType = {
666
+ "alloydb": alloydbMetadataSchema,
667
+ "athena": athenaMetadataSchema,
668
+ "big-query": bigqueryMetadataSchema,
669
+ "clickhouse": clickhouseMetadataSchema,
670
+ "databricks": databricksMetadataSchema,
671
+ "dremio": dremioMetadataSchema,
672
+ "mariadb": mariadbMetadataSchema,
673
+ "materialize": materializeMetadataSchema,
674
+ "mindsdb": mindsdbMetadataSchema,
675
+ "mongodb": mongodbMetadataSchema,
676
+ "mysql": mysqlMetadataSchema,
677
+ "pandas-dataframe": pandasDataframeMetadataSchema,
678
+ "pgsql": pgsqlMetadataSchema,
679
+ "redshift": redshiftMetadataSchema,
680
+ "snowflake": snowflakeMetadataSchema,
681
+ "spanner": spannerMetadataSchema,
682
+ "sql-server": sqlServerMetadataSchema,
683
+ "trino": trinoMetadataSchema
684
+ };
685
+
686
+ //#endregion
687
+ //#region src/database-integration-types.ts
688
+ const sqlIntegrationTypes = [
689
+ "alloydb",
690
+ "athena",
691
+ "big-query",
692
+ "clickhouse",
693
+ "databricks",
694
+ "dremio",
695
+ "mariadb",
696
+ "materialize",
697
+ "mindsdb",
698
+ "mysql",
699
+ "pandas-dataframe",
700
+ "pgsql",
701
+ "redshift",
702
+ "snowflake",
703
+ "spanner",
704
+ "sql-server",
705
+ "trino"
706
+ ];
707
+ const databaseIntegrationTypes = [...sqlIntegrationTypes, "mongodb"];
708
+ const databaseIntegrationTypesWithSslSupport = [
709
+ "clickhouse",
710
+ "dremio",
711
+ "mariadb",
712
+ "mindsdb",
713
+ "mongodb",
714
+ "mysql",
715
+ "pgsql",
716
+ "redshift",
717
+ "trino"
718
+ ];
719
+
720
+ //#endregion
721
+ exports.AwsAuthMethods = AwsAuthMethods;
722
+ exports.BigQueryAuthMethods = BigQueryAuthMethods;
723
+ exports.BigQueryServiceAccountParseError = BigQueryServiceAccountParseError;
724
+ exports.DatabaseAuthMethods = DatabaseAuthMethods;
725
+ exports.SnowflakeAuthMethods = SnowflakeAuthMethods;
726
+ exports.SpannerServiceAccountParseError = SpannerServiceAccountParseError;
727
+ exports.databaseIntegrationTypes = databaseIntegrationTypes;
728
+ exports.databaseIntegrationTypesWithSslSupport = databaseIntegrationTypesWithSslSupport;
729
+ exports.databaseMetadataSchemasByType = databaseMetadataSchemasByType;
730
+ exports.getIntegrationListEnv = getIntegrationListEnv;
731
+ exports.getSqlAlchemyInput = getSqlAlchemyInput;
732
+ exports.isFederatedAuthMetadata = isFederatedAuthMetadata;
733
+ exports.isFederatedAuthMethod = isFederatedAuthMethod;
734
+ exports.sqlIntegrationTypes = sqlIntegrationTypes;