@deepnote/database-integrations 1.4.3 → 1.5.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.js CHANGED
@@ -1,4 +1,6 @@
1
- import z$1, { z } from "zod";
1
+ import z, { z as z$1 } from "zod";
2
+ import { isMap, isSeq, parseDocument } from "yaml";
3
+ import { parseYaml } from "@deepnote/blocks";
2
4
 
3
5
  //#region src/sql-integration-auth-methods.ts
4
6
  const AwsAuthMethods = {
@@ -43,237 +45,239 @@ function isFederatedAuthMetadata(metadata) {
43
45
 
44
46
  //#endregion
45
47
  //#region src/database-integration-metadata-schemas.ts
46
- const athenaMetadataSchema = z.object({
47
- access_key_id: z.string(),
48
- region: z.string(),
49
- s3_output_path: z.string(),
50
- secret_access_key: z.string(),
51
- workgroup: z.string().optional()
48
+ const athenaMetadataSchema = z$1.object({
49
+ access_key_id: z$1.string(),
50
+ region: z$1.string(),
51
+ s3_output_path: z$1.string(),
52
+ secret_access_key: z$1.string(),
53
+ workgroup: z$1.string().optional()
52
54
  });
53
- const bigqueryMetadataSchema = z.discriminatedUnion("authMethod", [z.object({
54
- authMethod: z.literal(BigQueryAuthMethods.ServiceAccount).optional(),
55
- service_account: z.string()
56
- }), z.object({
57
- authMethod: z.literal(BigQueryAuthMethods.GoogleOauth),
58
- project: z.string(),
59
- clientId: z.string(),
60
- clientSecret: z.string()
55
+ const bigqueryMetadataSchema = z$1.discriminatedUnion("authMethod", [z$1.object({
56
+ authMethod: z$1.literal(BigQueryAuthMethods.ServiceAccount).optional(),
57
+ service_account: z$1.string()
58
+ }), z$1.object({
59
+ authMethod: z$1.literal(BigQueryAuthMethods.GoogleOauth),
60
+ project: z$1.string(),
61
+ clientId: z$1.string(),
62
+ clientSecret: z$1.string()
61
63
  })]);
62
- const clickhouseMetadataSchema = z.object({
63
- host: z.string(),
64
- user: z.string(),
65
- password: z.string().optional(),
66
- database: z.string(),
67
- port: z.string().optional(),
68
- sshEnabled: z.boolean().optional(),
69
- sshHost: z.string().optional(),
70
- sshPort: z.string().optional(),
71
- sshUser: z.string().optional(),
72
- sslEnabled: z.boolean().optional(),
73
- caCertificateName: z.string().optional(),
74
- caCertificateText: z.string().optional()
64
+ const clickhouseMetadataSchema = z$1.object({
65
+ host: z$1.string(),
66
+ user: z$1.string(),
67
+ password: z$1.string().optional(),
68
+ database: z$1.string(),
69
+ port: z$1.string().optional(),
70
+ sshEnabled: z$1.boolean().optional(),
71
+ sshHost: z$1.string().optional(),
72
+ sshPort: z$1.string().optional(),
73
+ sshUser: z$1.string().optional(),
74
+ sslEnabled: z$1.boolean().optional(),
75
+ caCertificateName: z$1.string().optional(),
76
+ caCertificateText: z$1.string().optional()
75
77
  });
76
- const databricksMetadataSchema = z.object({
77
- host: z.string(),
78
- httpPath: z.string(),
79
- token: z.string(),
80
- port: z.string(),
81
- schema: z.string().optional(),
82
- catalog: z.string().optional(),
83
- sshEnabled: z.boolean().optional(),
84
- sshHost: z.string().optional(),
85
- sshPort: z.string().optional(),
86
- sshUser: z.string().optional()
78
+ const cloudSqlMetadataSchema = z$1.object({ service_account: z$1.string() });
79
+ const databricksMetadataSchema = z$1.object({
80
+ host: z$1.string(),
81
+ httpPath: z$1.string(),
82
+ token: z$1.string(),
83
+ port: z$1.string(),
84
+ schema: z$1.string().optional(),
85
+ catalog: z$1.string().optional(),
86
+ sshEnabled: z$1.boolean().optional(),
87
+ sshHost: z$1.string().optional(),
88
+ sshPort: z$1.string().optional(),
89
+ sshUser: z$1.string().optional()
87
90
  });
88
- const dremioMetadataSchema = z.object({
89
- schema: z.string(),
90
- host: z.string(),
91
- port: z.string(),
92
- token: z.string(),
93
- sshEnabled: z.boolean().optional(),
94
- sshHost: z.string().optional(),
95
- sshPort: z.string().optional(),
96
- sshUser: z.string().optional()
91
+ const dremioMetadataSchema = z$1.object({
92
+ schema: z$1.string(),
93
+ host: z$1.string(),
94
+ port: z$1.string(),
95
+ token: z$1.string(),
96
+ sshEnabled: z$1.boolean().optional(),
97
+ sshHost: z$1.string().optional(),
98
+ sshPort: z$1.string().optional(),
99
+ sshUser: z$1.string().optional()
97
100
  });
98
- const mongodbMetadataSchema = z.object({
99
- connection_string: z.string(),
100
- rawConnectionString: z.string().optional(),
101
- prefix: z.string().optional(),
102
- host: z.string().optional(),
103
- port: z.string().optional(),
104
- user: z.string().optional(),
105
- password: z.string().optional(),
106
- database: z.string().optional(),
107
- options: z.string().optional(),
108
- sshEnabled: z.boolean().optional(),
109
- sshHost: z.string().optional(),
110
- sshPort: z.string().optional(),
111
- sshUser: z.string().optional(),
112
- sslEnabled: z.boolean().optional(),
113
- caCertificateName: z.string().optional(),
114
- caCertificateText: z.string().optional()
101
+ const mongodbMetadataSchema = z$1.object({
102
+ connection_string: z$1.string(),
103
+ rawConnectionString: z$1.string().optional(),
104
+ prefix: z$1.string().optional(),
105
+ host: z$1.string().optional(),
106
+ port: z$1.string().optional(),
107
+ user: z$1.string().optional(),
108
+ password: z$1.string().optional(),
109
+ database: z$1.string().optional(),
110
+ options: z$1.string().optional(),
111
+ sshEnabled: z$1.boolean().optional(),
112
+ sshHost: z$1.string().optional(),
113
+ sshPort: z$1.string().optional(),
114
+ sshUser: z$1.string().optional(),
115
+ sslEnabled: z$1.boolean().optional(),
116
+ caCertificateName: z$1.string().optional(),
117
+ caCertificateText: z$1.string().optional()
115
118
  });
116
- const pandasDataframeMetadataSchema = z.object({});
117
- const commonRedshiftMetadataSchema = z.object({
118
- database: z.string(),
119
- host: z.string(),
120
- port: z.string().optional(),
121
- sshEnabled: z.boolean().optional(),
122
- sshHost: z.string().optional(),
123
- sshPort: z.string().optional(),
124
- sshUser: z.string().optional(),
125
- sslEnabled: z.boolean().optional(),
126
- caCertificateName: z.string().optional(),
127
- caCertificateText: z.string().optional()
119
+ const pandasDataframeMetadataSchema = z$1.object({});
120
+ const commonRedshiftMetadataSchema = z$1.object({
121
+ database: z$1.string(),
122
+ host: z$1.string(),
123
+ port: z$1.string().optional(),
124
+ sshEnabled: z$1.boolean().optional(),
125
+ sshHost: z$1.string().optional(),
126
+ sshPort: z$1.string().optional(),
127
+ sshUser: z$1.string().optional(),
128
+ sslEnabled: z$1.boolean().optional(),
129
+ caCertificateName: z$1.string().optional(),
130
+ caCertificateText: z$1.string().optional()
128
131
  });
129
- const redshiftMetadataSchema = z.preprocess((data) => {
132
+ const redshiftMetadataSchema = z$1.preprocess((data) => {
130
133
  if (typeof data === "object" && data !== null && (!("authMethod" in data) || !data.authMethod)) return {
131
134
  ...data,
132
135
  authMethod: DatabaseAuthMethods.UsernameAndPassword
133
136
  };
134
137
  return data;
135
- }, z.union([
138
+ }, z$1.union([
136
139
  commonRedshiftMetadataSchema.extend({
137
- authMethod: z.literal(DatabaseAuthMethods.UsernameAndPassword).optional(),
138
- user: z.string(),
139
- password: z.string()
140
+ authMethod: z$1.literal(DatabaseAuthMethods.UsernameAndPassword).optional(),
141
+ user: z$1.string(),
142
+ password: z$1.string()
140
143
  }),
141
144
  commonRedshiftMetadataSchema.extend({
142
- authMethod: z.literal(AwsAuthMethods.IamRole),
143
- roleArn: z.string(),
144
- roleExternalId: z.string(),
145
- roleNonce: z.string()
145
+ authMethod: z$1.literal(AwsAuthMethods.IamRole),
146
+ roleArn: z$1.string(),
147
+ roleExternalId: z$1.string(),
148
+ roleNonce: z$1.string()
146
149
  }),
147
- commonRedshiftMetadataSchema.extend({ authMethod: z.literal(DatabaseAuthMethods.IndividualCredentials) })
150
+ commonRedshiftMetadataSchema.extend({ authMethod: z$1.literal(DatabaseAuthMethods.IndividualCredentials) })
148
151
  ]));
149
- const commonSnowflakeMetadataSchema = z.object({
150
- accountName: z.string(),
151
- warehouse: z.string().optional(),
152
- database: z.string().optional(),
153
- role: z.string().optional(),
154
- dbt: z.boolean().optional(),
155
- dbtServiceToken: z.string().optional(),
156
- dbtPrimaryJobId: z.string().optional(),
157
- dbtProxyServerUrl: z.string().optional()
152
+ const commonSnowflakeMetadataSchema = z$1.object({
153
+ accountName: z$1.string(),
154
+ warehouse: z$1.string().optional(),
155
+ database: z$1.string().optional(),
156
+ role: z$1.string().optional(),
157
+ dbt: z$1.boolean().optional(),
158
+ dbtServiceToken: z$1.string().optional(),
159
+ dbtPrimaryJobId: z$1.string().optional(),
160
+ dbtProxyServerUrl: z$1.string().optional()
158
161
  });
159
- const snowflakeMetadataSchema = z.preprocess((data) => {
162
+ const snowflakeMetadataSchema = z$1.preprocess((data) => {
160
163
  if (typeof data === "object" && data !== null && (!("authMethod" in data) || !data.authMethod)) return {
161
164
  ...data,
162
165
  authMethod: SnowflakeAuthMethods.Password
163
166
  };
164
167
  return data;
165
- }, z.discriminatedUnion("authMethod", [
168
+ }, z$1.discriminatedUnion("authMethod", [
166
169
  commonSnowflakeMetadataSchema.extend({
167
- authMethod: z.literal(SnowflakeAuthMethods.Password).optional(),
168
- username: z.string(),
169
- password: z.string()
170
+ authMethod: z$1.literal(SnowflakeAuthMethods.Password).optional(),
171
+ username: z$1.string(),
172
+ password: z$1.string()
170
173
  }),
171
174
  commonSnowflakeMetadataSchema.extend({
172
- authMethod: z.literal(SnowflakeAuthMethods.Okta),
173
- clientId: z.string(),
174
- clientSecret: z.string(),
175
- oktaSubdomain: z.string(),
176
- identityProvider: z.string(),
177
- authorizationServer: z.string()
175
+ authMethod: z$1.literal(SnowflakeAuthMethods.Okta),
176
+ clientId: z$1.string(),
177
+ clientSecret: z$1.string(),
178
+ oktaSubdomain: z$1.string(),
179
+ identityProvider: z$1.string(),
180
+ authorizationServer: z$1.string()
178
181
  }),
179
182
  commonSnowflakeMetadataSchema.extend({
180
- authMethod: z.literal(SnowflakeAuthMethods.NativeSnowflake),
181
- clientId: z.string(),
182
- clientSecret: z.string()
183
+ authMethod: z$1.literal(SnowflakeAuthMethods.NativeSnowflake),
184
+ clientId: z$1.string(),
185
+ clientSecret: z$1.string()
183
186
  }),
184
187
  commonSnowflakeMetadataSchema.extend({
185
- authMethod: z.literal(SnowflakeAuthMethods.AzureAd),
186
- clientId: z.string(),
187
- clientSecret: z.string(),
188
- resource: z.string(),
189
- tenant: z.string()
188
+ authMethod: z$1.literal(SnowflakeAuthMethods.AzureAd),
189
+ clientId: z$1.string(),
190
+ clientSecret: z$1.string(),
191
+ resource: z$1.string(),
192
+ tenant: z$1.string()
190
193
  }),
191
- commonSnowflakeMetadataSchema.extend({ authMethod: z.literal(SnowflakeAuthMethods.KeyPair) }),
194
+ commonSnowflakeMetadataSchema.extend({ authMethod: z$1.literal(SnowflakeAuthMethods.KeyPair) }),
192
195
  commonSnowflakeMetadataSchema.extend({
193
- authMethod: z.literal(SnowflakeAuthMethods.ServiceAccountKeyPair),
194
- username: z.string(),
195
- privateKey: z.string(),
196
- privateKeyPassphrase: z.string().optional()
196
+ authMethod: z$1.literal(SnowflakeAuthMethods.ServiceAccountKeyPair),
197
+ username: z$1.string(),
198
+ privateKey: z$1.string(),
199
+ privateKeyPassphrase: z$1.string().optional()
197
200
  })
198
201
  ]));
199
- const spannerMetadataSchema = z.object({
200
- service_account: z.string(),
201
- dataBoostEnabled: z.boolean(),
202
- instance: z.string(),
203
- database: z.string()
202
+ const spannerMetadataSchema = z$1.object({
203
+ service_account: z$1.string(),
204
+ dataBoostEnabled: z$1.boolean(),
205
+ instance: z$1.string(),
206
+ database: z$1.string()
204
207
  });
205
- const trinoBaseMetadataSchema = z.object({
206
- host: z.string(),
207
- port: z.string().optional(),
208
- database: z.string(),
209
- sshEnabled: z.boolean().optional(),
210
- sshHost: z.string().optional(),
211
- sshPort: z.string().optional(),
212
- sshUser: z.string().optional(),
213
- sslEnabled: z.boolean().optional(),
214
- caCertificateName: z.string().optional(),
215
- caCertificateText: z.string().optional()
208
+ const trinoBaseMetadataSchema = z$1.object({
209
+ host: z$1.string(),
210
+ port: z$1.string().optional(),
211
+ database: z$1.string(),
212
+ sshEnabled: z$1.boolean().optional(),
213
+ sshHost: z$1.string().optional(),
214
+ sshPort: z$1.string().optional(),
215
+ sshUser: z$1.string().optional(),
216
+ sslEnabled: z$1.boolean().optional(),
217
+ caCertificateName: z$1.string().optional(),
218
+ caCertificateText: z$1.string().optional()
216
219
  });
217
220
  const trinoUsernamePasswordMetadataSchema = trinoBaseMetadataSchema.extend({
218
- authMethod: z.literal(TrinoAuthMethods.Password).nullish(),
219
- user: z.string(),
220
- password: z.string()
221
+ authMethod: z$1.literal(TrinoAuthMethods.Password).nullish(),
222
+ user: z$1.string(),
223
+ password: z$1.string()
221
224
  });
222
225
  const trinoOAuthMetadataSchema = trinoBaseMetadataSchema.extend({
223
- authMethod: z.literal(TrinoAuthMethods.Oauth),
224
- clientId: z.string(),
225
- clientSecret: z.string(),
226
- authUrl: z.string().url(),
227
- tokenUrl: z.string().url()
226
+ authMethod: z$1.literal(TrinoAuthMethods.Oauth),
227
+ clientId: z$1.string(),
228
+ clientSecret: z$1.string(),
229
+ authUrl: z$1.string().url(),
230
+ tokenUrl: z$1.string().url()
228
231
  });
229
- const trinoMetadataSchema = z.discriminatedUnion("authMethod", [trinoUsernamePasswordMetadataSchema, trinoOAuthMetadataSchema]);
230
- const commonDatabaseSchema = z.object({
231
- host: z.string(),
232
- user: z.string(),
233
- password: z.string(),
234
- database: z.string(),
235
- sshEnabled: z.boolean().optional(),
236
- sshHost: z.string().optional(),
237
- sshPort: z.string().optional(),
238
- sshUser: z.string().optional()
232
+ const trinoMetadataSchema = z$1.discriminatedUnion("authMethod", [trinoUsernamePasswordMetadataSchema, trinoOAuthMetadataSchema]);
233
+ const commonDatabaseSchema = z$1.object({
234
+ host: z$1.string(),
235
+ user: z$1.string(),
236
+ password: z$1.string(),
237
+ database: z$1.string(),
238
+ sshEnabled: z$1.boolean().optional(),
239
+ sshHost: z$1.string().optional(),
240
+ sshPort: z$1.string().optional(),
241
+ sshUser: z$1.string().optional()
239
242
  });
240
243
  const alloydbMetadataSchema = commonDatabaseSchema.extend({
241
- port: z.string().optional(),
242
- sslEnabled: z.boolean().optional(),
243
- caCertificateName: z.string().optional(),
244
- caCertificateText: z.string().optional()
244
+ port: z$1.string().optional(),
245
+ sslEnabled: z$1.boolean().optional(),
246
+ caCertificateName: z$1.string().optional(),
247
+ caCertificateText: z$1.string().optional()
245
248
  });
246
249
  const mariadbMetadataSchema = commonDatabaseSchema.extend({
247
- port: z.string().optional(),
248
- sslEnabled: z.boolean().optional(),
249
- caCertificateName: z.string().optional(),
250
- caCertificateText: z.string().optional()
250
+ port: z$1.string().optional(),
251
+ sslEnabled: z$1.boolean().optional(),
252
+ caCertificateName: z$1.string().optional(),
253
+ caCertificateText: z$1.string().optional()
251
254
  });
252
255
  const mindsdbMetadataSchema = commonDatabaseSchema.extend({
253
- port: z.string().optional(),
254
- sslEnabled: z.boolean().optional(),
255
- caCertificateName: z.string().optional(),
256
- caCertificateText: z.string().optional()
256
+ port: z$1.string().optional(),
257
+ sslEnabled: z$1.boolean().optional(),
258
+ caCertificateName: z$1.string().optional(),
259
+ caCertificateText: z$1.string().optional()
257
260
  });
258
261
  const mysqlMetadataSchema = commonDatabaseSchema.extend({
259
- port: z.string().optional(),
260
- sslEnabled: z.boolean().optional(),
261
- caCertificateName: z.string().optional(),
262
- caCertificateText: z.string().optional()
262
+ port: z$1.string().optional(),
263
+ sslEnabled: z$1.boolean().optional(),
264
+ caCertificateName: z$1.string().optional(),
265
+ caCertificateText: z$1.string().optional()
263
266
  });
264
267
  const pgsqlMetadataSchema = commonDatabaseSchema.extend({
265
- port: z.string().optional(),
266
- sslEnabled: z.boolean().optional(),
267
- caCertificateName: z.string().optional(),
268
- caCertificateText: z.string().optional()
268
+ port: z$1.string().optional(),
269
+ sslEnabled: z$1.boolean().optional(),
270
+ caCertificateName: z$1.string().optional(),
271
+ caCertificateText: z$1.string().optional()
269
272
  });
270
- const materializeMetadataSchema = pgsqlMetadataSchema.extend({ cluster: z.string() });
271
- const sqlServerMetadataSchema = commonDatabaseSchema.extend({ port: z.string() });
273
+ const materializeMetadataSchema = pgsqlMetadataSchema.extend({ cluster: z$1.string() });
274
+ const sqlServerMetadataSchema = commonDatabaseSchema.extend({ port: z$1.string() });
272
275
  const databaseMetadataSchemasByType = {
273
276
  "alloydb": alloydbMetadataSchema,
274
277
  "athena": athenaMetadataSchema,
275
278
  "big-query": bigqueryMetadataSchema,
276
279
  "clickhouse": clickhouseMetadataSchema,
280
+ "cloud-sql": cloudSqlMetadataSchema,
277
281
  "databricks": databricksMetadataSchema,
278
282
  "dremio": dremioMetadataSchema,
279
283
  "mariadb": mariadbMetadataSchema,
@@ -292,89 +296,94 @@ const databaseMetadataSchemasByType = {
292
296
 
293
297
  //#endregion
294
298
  //#region src/database-integration-config.ts
295
- const commonIntegrationConfig = z$1.object({
296
- id: z$1.string(),
297
- name: z$1.string()
299
+ const commonIntegrationConfig = z.object({
300
+ id: z.string(),
301
+ name: z.string()
298
302
  });
299
- const databaseIntegrationConfigSchema = z$1.discriminatedUnion("type", [
303
+ const databaseIntegrationConfigSchema = z.discriminatedUnion("type", [
300
304
  commonIntegrationConfig.extend({
301
- type: z$1.literal("alloydb"),
305
+ type: z.literal("alloydb"),
302
306
  metadata: databaseMetadataSchemasByType.alloydb,
303
- federated_auth_method: z$1.null().optional()
307
+ federated_auth_method: z.null().optional()
304
308
  }),
305
309
  commonIntegrationConfig.extend({
306
- type: z$1.literal("athena"),
310
+ type: z.literal("athena"),
307
311
  metadata: databaseMetadataSchemasByType.athena,
308
- federated_auth_method: z$1.null().optional()
312
+ federated_auth_method: z.null().optional()
309
313
  }),
310
314
  commonIntegrationConfig.extend({
311
- type: z$1.literal("big-query"),
315
+ type: z.literal("big-query"),
312
316
  metadata: databaseMetadataSchemasByType["big-query"],
313
- federated_auth_method: z$1.enum(["service-account", "google-oauth"]).optional().nullable()
317
+ federated_auth_method: z.enum(["service-account", "google-oauth"]).optional().nullable()
314
318
  }),
315
319
  commonIntegrationConfig.extend({
316
- type: z$1.literal("clickhouse"),
320
+ type: z.literal("clickhouse"),
317
321
  metadata: databaseMetadataSchemasByType.clickhouse,
318
- federated_auth_method: z$1.null().optional()
322
+ federated_auth_method: z.null().optional()
323
+ }),
324
+ commonIntegrationConfig.extend({
325
+ type: z.literal("cloud-sql"),
326
+ metadata: databaseMetadataSchemasByType["cloud-sql"],
327
+ federated_auth_method: z.null().optional()
319
328
  }),
320
329
  commonIntegrationConfig.extend({
321
- type: z$1.literal("databricks"),
330
+ type: z.literal("databricks"),
322
331
  metadata: databaseMetadataSchemasByType.databricks,
323
- federated_auth_method: z$1.null().optional()
332
+ federated_auth_method: z.null().optional()
324
333
  }),
325
334
  commonIntegrationConfig.extend({
326
- type: z$1.literal("dremio"),
335
+ type: z.literal("dremio"),
327
336
  metadata: databaseMetadataSchemasByType.dremio,
328
- federated_auth_method: z$1.null().optional()
337
+ federated_auth_method: z.null().optional()
329
338
  }),
330
339
  commonIntegrationConfig.extend({
331
- type: z$1.literal("mariadb"),
340
+ type: z.literal("mariadb"),
332
341
  metadata: databaseMetadataSchemasByType.mariadb,
333
- federated_auth_method: z$1.null().optional()
342
+ federated_auth_method: z.null().optional()
334
343
  }),
335
344
  commonIntegrationConfig.extend({
336
- type: z$1.literal("materialize"),
345
+ type: z.literal("materialize"),
337
346
  metadata: databaseMetadataSchemasByType.materialize,
338
- federated_auth_method: z$1.null().optional()
347
+ federated_auth_method: z.null().optional()
339
348
  }),
340
349
  commonIntegrationConfig.extend({
341
- type: z$1.literal("mindsdb"),
350
+ type: z.literal("mindsdb"),
342
351
  metadata: databaseMetadataSchemasByType.mindsdb,
343
- federated_auth_method: z$1.null().optional()
352
+ federated_auth_method: z.null().optional()
344
353
  }),
345
354
  commonIntegrationConfig.extend({
346
- type: z$1.literal("mongodb"),
355
+ type: z.literal("mongodb"),
347
356
  metadata: databaseMetadataSchemasByType.mongodb,
348
- federated_auth_method: z$1.null().optional()
357
+ federated_auth_method: z.null().optional()
349
358
  }),
350
359
  commonIntegrationConfig.extend({
351
- type: z$1.literal("mysql"),
360
+ type: z.literal("mysql"),
352
361
  metadata: databaseMetadataSchemasByType.mysql,
353
- federated_auth_method: z$1.null().optional()
362
+ federated_auth_method: z.null().optional()
354
363
  }),
355
364
  commonIntegrationConfig.extend({
356
- type: z$1.literal("pandas-dataframe"),
365
+ type: z.literal("pandas-dataframe"),
357
366
  metadata: databaseMetadataSchemasByType["pandas-dataframe"],
358
- federated_auth_method: z$1.null().optional()
367
+ federated_auth_method: z.null().optional()
359
368
  }),
360
369
  commonIntegrationConfig.extend({
361
- type: z$1.literal("pgsql"),
370
+ type: z.literal("pgsql"),
362
371
  metadata: databaseMetadataSchemasByType.pgsql,
363
- federated_auth_method: z$1.null().optional()
372
+ federated_auth_method: z.null().optional()
364
373
  }),
365
374
  commonIntegrationConfig.extend({
366
- type: z$1.literal("redshift"),
375
+ type: z.literal("redshift"),
367
376
  metadata: databaseMetadataSchemasByType.redshift,
368
- federated_auth_method: z$1.enum([
377
+ federated_auth_method: z.enum([
369
378
  "username-and-password",
370
379
  "iam-role",
371
380
  "individual-credentials"
372
381
  ]).optional().nullable()
373
382
  }),
374
383
  commonIntegrationConfig.extend({
375
- type: z$1.literal("snowflake"),
384
+ type: z.literal("snowflake"),
376
385
  metadata: databaseMetadataSchemasByType.snowflake,
377
- federated_auth_method: z$1.enum([
386
+ federated_auth_method: z.enum([
378
387
  "okta",
379
388
  "snowflake",
380
389
  "azure",
@@ -384,19 +393,19 @@ const databaseIntegrationConfigSchema = z$1.discriminatedUnion("type", [
384
393
  ]).optional().nullable()
385
394
  }),
386
395
  commonIntegrationConfig.extend({
387
- type: z$1.literal("spanner"),
396
+ type: z.literal("spanner"),
388
397
  metadata: databaseMetadataSchemasByType.spanner,
389
- federated_auth_method: z$1.null().optional()
398
+ federated_auth_method: z.null().optional()
390
399
  }),
391
400
  commonIntegrationConfig.extend({
392
- type: z$1.literal("sql-server"),
401
+ type: z.literal("sql-server"),
393
402
  metadata: databaseMetadataSchemasByType["sql-server"],
394
- federated_auth_method: z$1.null().optional()
403
+ federated_auth_method: z.null().optional()
395
404
  }),
396
405
  commonIntegrationConfig.extend({
397
- type: z$1.literal("trino"),
406
+ type: z.literal("trino"),
398
407
  metadata: databaseMetadataSchemasByType.trino,
399
- federated_auth_method: z$1.enum(["trino-oauth", "password"]).optional().nullable()
408
+ federated_auth_method: z.enum(["trino-oauth", "password"]).optional().nullable()
400
409
  })
401
410
  ]);
402
411
 
@@ -543,6 +552,7 @@ function getSqlAlchemyInput(integration, params) {
543
552
  case "athena": return getAthenaSqlAlchemyInput(integration.metadata);
544
553
  case "big-query": return getBigQuerySqlAlchemyInput(integration.metadata);
545
554
  case "clickhouse": return getClickHouseSqlAlchemyInput(integration.id, params.projectRootDirectory, integration.metadata);
555
+ case "cloud-sql": return null;
546
556
  case "databricks": return getDatabricksSqlAlchemyInput(integration.metadata);
547
557
  case "dremio": return getDremioSqlAlchemyInput(integration.metadata);
548
558
  case "mariadb":
@@ -837,6 +847,7 @@ const sqlIntegrationTypes = [
837
847
  "athena",
838
848
  "big-query",
839
849
  "clickhouse",
850
+ "cloud-sql",
840
851
  "databricks",
841
852
  "dremio",
842
853
  "mariadb",
@@ -874,6 +885,200 @@ function isDatabaseIntegrationTypeWithSslSupport(type) {
874
885
  return databaseIntegrationTypesWithSslSupport.includes(type);
875
886
  }
876
887
 
888
+ //#endregion
889
+ //#region src/loading/api-error.ts
890
+ /**
891
+ * Error thrown when a Deepnote API request fails.
892
+ */
893
+ var ApiError = class extends Error {
894
+ statusCode;
895
+ constructor(statusCode, message) {
896
+ super(message);
897
+ this.name = "ApiError";
898
+ this.statusCode = statusCode;
899
+ }
900
+ };
901
+
902
+ //#endregion
903
+ //#region src/loading/constants.ts
904
+ /** Built-in integrations that don't require external configuration. */
905
+ const BUILTIN_INTEGRATIONS = new Set(["deepnote-dataframe-sql", "pandas-dataframe"]);
906
+ /** Default `.env` file name for storing integration secrets. */
907
+ const DEFAULT_ENV_FILE = ".env";
908
+ /** Default integrations file name. */
909
+ const DEFAULT_INTEGRATIONS_FILE = ".deepnote.env.yaml";
910
+ /** Default Deepnote API base URL. */
911
+ const DEFAULT_API_URL = "https://api.deepnote.com";
912
+
913
+ //#endregion
914
+ //#region src/loading/env-var-refs.ts
915
+ const ENV_VAR_REF_PREFIX = "env:";
916
+ function generateEnvVarName(integrationId, fieldPath) {
917
+ return `${integrationId.toUpperCase().replace(/-/g, "_")}__${fieldPath.toUpperCase()}`;
918
+ }
919
+ function parseEnvVarRef(value) {
920
+ if (typeof value !== "string") return null;
921
+ if (!value.startsWith(ENV_VAR_REF_PREFIX)) return null;
922
+ const varName = value.slice(4);
923
+ if (!varName) return null;
924
+ return {
925
+ prefix: "env",
926
+ varName
927
+ };
928
+ }
929
+ function createEnvVarRef(varName) {
930
+ return `${ENV_VAR_REF_PREFIX}${varName}`;
931
+ }
932
+ function isEnvVarRef(value) {
933
+ return typeof value === "string" && parseEnvVarRef(value) !== null;
934
+ }
935
+ function extractEnvVarName(value) {
936
+ if (typeof value !== "string") return null;
937
+ return parseEnvVarRef(value)?.varName ?? null;
938
+ }
939
+ /**
940
+ * Error thrown when an environment variable reference cannot be resolved.
941
+ */
942
+ var EnvVarResolutionError = class extends Error {
943
+ varName;
944
+ path;
945
+ constructor(varName, path) {
946
+ const pathInfo = path ? ` at "${path}"` : "";
947
+ super(`Environment variable "${varName}" is not defined${pathInfo}`);
948
+ this.name = "EnvVarResolutionError";
949
+ this.varName = varName;
950
+ this.path = path;
951
+ }
952
+ };
953
+ /**
954
+ * Recursively resolves environment variable references in an object using an explicit variable map.
955
+ * Replaces any string value matching `env:VAR_NAME` with the value from the provided vars map.
956
+ *
957
+ * @param obj - The object to process (can be any value: primitive, array, or object)
958
+ * @param vars - Map of variable names to values (e.g. from a parsed .env file, process.env, or a secret store)
959
+ * @param currentPath - Internal parameter for tracking the current path in the object (for error messages)
960
+ * @returns A new object with all env var references resolved
961
+ * @throws {EnvVarResolutionError} If an environment variable reference cannot be resolved
962
+ */
963
+ function resolveEnvVarRefsFromMap(obj, vars, currentPath) {
964
+ if (obj === null || obj === void 0) return obj;
965
+ if (typeof obj === "string") {
966
+ const parsed = parseEnvVarRef(obj);
967
+ if (parsed) {
968
+ const envValue = vars[parsed.varName];
969
+ if (envValue === void 0) throw new EnvVarResolutionError(parsed.varName, currentPath);
970
+ return envValue;
971
+ }
972
+ return obj;
973
+ }
974
+ if (Array.isArray(obj)) return obj.map((item, index) => {
975
+ return resolveEnvVarRefsFromMap(item, vars, currentPath ? `${currentPath}[${index}]` : `[${index}]`);
976
+ });
977
+ if (typeof obj === "object") {
978
+ const result = {};
979
+ for (const [key, value] of Object.entries(obj)) result[key] = resolveEnvVarRefsFromMap(value, vars, currentPath ? `${currentPath}.${key}` : key);
980
+ return result;
981
+ }
982
+ return obj;
983
+ }
984
+
985
+ //#endregion
986
+ //#region src/loading/fetch-integrations.ts
987
+ /**
988
+ * Schema for a single integration from the API.
989
+ */
990
+ const apiIntegrationSchema = z$1.object({
991
+ id: z$1.string(),
992
+ name: z$1.string(),
993
+ type: z$1.string(),
994
+ metadata: z$1.unknown(),
995
+ is_public: z$1.boolean(),
996
+ created_at: z$1.string(),
997
+ updated_at: z$1.string(),
998
+ federated_auth_method: z$1.string().nullable()
999
+ }).passthrough();
1000
+ /**
1001
+ * Schema for the full API response.
1002
+ */
1003
+ const apiResponseSchema = z$1.object({ integrations: z$1.array(apiIntegrationSchema) }).passthrough();
1004
+ /**
1005
+ * Fetch integrations from the Deepnote API.
1006
+ *
1007
+ * Uses the global `fetch`, so it works in Node (18+) and browser-like environments alike.
1008
+ *
1009
+ * @param baseUrl - The base URL of the Deepnote API
1010
+ * @param token - The authentication token
1011
+ * @param integrationIds - Optional list of integration IDs to fetch. When provided, only these integrations are returned.
1012
+ * @returns Array of integrations from the API
1013
+ * @throws ApiError if the request fails
1014
+ */
1015
+ async function fetchIntegrations(baseUrl, token, integrationIds) {
1016
+ const endpoint = new URL(`${baseUrl}/v2/integrations`);
1017
+ endpoint.searchParams.set("includeMetadata", "true");
1018
+ if (integrationIds && integrationIds.length > 0) endpoint.searchParams.set("integrationIds", integrationIds.join(","));
1019
+ const url = endpoint.toString();
1020
+ const response = await fetch(url, {
1021
+ method: "GET",
1022
+ headers: {
1023
+ Authorization: `Bearer ${token}`,
1024
+ "Content-Type": "application/json"
1025
+ }
1026
+ });
1027
+ if (!response.ok) {
1028
+ if (response.status === 401) throw new ApiError(401, "Authentication failed. Please check your API token.");
1029
+ if (response.status === 403) throw new ApiError(403, "Access denied. You may not have permission to access integrations.");
1030
+ throw new ApiError(response.status, `API request failed with status ${response.status}: ${response.statusText}`);
1031
+ }
1032
+ const json = await response.json();
1033
+ const parseResult = apiResponseSchema.safeParse(json);
1034
+ if (!parseResult.success) throw new Error(`Invalid API response: ${parseResult.error.message}`);
1035
+ return parseResult.data.integrations;
1036
+ }
1037
+
1038
+ //#endregion
1039
+ //#region src/loading/integrations-document.ts
1040
+ /**
1041
+ * Parse integrations YAML content into a mutable `yaml` Document that preserves
1042
+ * comments and formatting. Returns `null` for empty content.
1043
+ *
1044
+ * This is the content-accepting counterpart of the Node-only `readIntegrationsDocument`.
1045
+ */
1046
+ function parseIntegrationsDocument(content) {
1047
+ if (!content.trim()) return null;
1048
+ return parseDocument(content, {
1049
+ strict: true,
1050
+ version: "1.2"
1051
+ });
1052
+ }
1053
+ /**
1054
+ * Serialize an integrations Document back to YAML text, preserving comments and
1055
+ * formatting and avoiding line wrapping.
1056
+ */
1057
+ function serializeIntegrationsDocument(doc) {
1058
+ return doc.toString({ lineWidth: 0 });
1059
+ }
1060
+
1061
+ //#endregion
1062
+ //#region src/loading/integrations-file-schema.ts
1063
+ /**
1064
+ * Schema for the integrations YAML file structure.
1065
+ * Uses loose validation to accept any array of objects,
1066
+ * allowing per-entry validation to report specific issues.
1067
+ *
1068
+ * Example file format:
1069
+ * ```yaml
1070
+ * integrations:
1071
+ * - id: my-postgres
1072
+ * name: My PostgreSQL
1073
+ * type: pgsql
1074
+ * metadata:
1075
+ * host: localhost
1076
+ * ...
1077
+ * ```
1078
+ */
1079
+ const baseIntegrationsFileSchema = z$1.object({ integrations: z$1.array(z$1.record(z$1.unknown())).optional().default([]) });
1080
+ const integrationsFileSchema = z$1.object({ integrations: z$1.array(databaseIntegrationConfigSchema) });
1081
+
877
1082
  //#endregion
878
1083
  //#region src/secret-field-paths.ts
879
1084
  /**
@@ -896,6 +1101,7 @@ const SECRET_PATHS = {
896
1101
  dremio: ["token"],
897
1102
  athena: ["secret_access_key"],
898
1103
  spanner: ["service_account"],
1104
+ "cloud-sql": ["service_account"],
899
1105
  mongodb: [
900
1106
  "password",
901
1107
  "connection_string",
@@ -932,4 +1138,339 @@ function getSecretFieldPaths(type) {
932
1138
  }
933
1139
 
934
1140
  //#endregion
935
- export { AwsAuthMethods, BigQueryAuthMethods, BigQueryServiceAccountParseError, DatabaseAuthMethods, SnowflakeAuthMethods, SpannerServiceAccountParseError, TrinoAuthMethods, databaseIntegrationConfigSchema, databaseIntegrationTypes, databaseIntegrationTypesWithSslSupport, databaseMetadataSchemasByType, federatedAuthMethods, getEnvironmentVariablesForIntegrations, getSecretFieldPaths, getSnowflakeFederatedAuthSqlAlchemyInput, getSqlAlchemyInput, isDatabaseIntegrationType, isDatabaseIntegrationTypeWithSslSupport, isFederatedAuthMetadata, isFederatedAuthMethod, isSqlIntegrationType, sqlIntegrationTypes };
1141
+ //#region src/loading/merge-integrations.ts
1142
+ /**
1143
+ * JSON schema URL for the integrations file.
1144
+ * TODO - change to main branch when the PR is merged into main
1145
+ */
1146
+ const JSON_SCHEMA_URL = "https://raw.githubusercontent.com/deepnote/deepnote/refs/heads/tk/integrations-config-file-schema/json-schemas/integrations-file-schema.json";
1147
+ /**
1148
+ * Schema comment for the YAML file.
1149
+ */
1150
+ const SCHEMA_COMMENT = `yaml-language-server: $schema=${JSON_SCHEMA_URL}`;
1151
+ /**
1152
+ * Error thrown when the integrations property has an invalid type.
1153
+ */
1154
+ var InvalidIntegrationsTypeError = class extends Error {
1155
+ constructor() {
1156
+ super(`Invalid 'integrations' property: expected a list`);
1157
+ this.name = "InvalidIntegrationsTypeError";
1158
+ }
1159
+ };
1160
+ /**
1161
+ * Get the integrations sequence from a YAML Document, creating an empty one if it doesn't exist.
1162
+ * If the integrations property is missing or null, creates an empty array and returns a reference to it.
1163
+ * Throws InvalidIntegrationsTypeError if integrations exists but is not an array.
1164
+ */
1165
+ function getOrCreateIntegrationsFromDocument(doc) {
1166
+ const integrations = doc.get("integrations");
1167
+ if (integrations == null) {
1168
+ const emptySeq = doc.createNode([]);
1169
+ emptySeq.flow = false;
1170
+ doc.set("integrations", emptySeq);
1171
+ return emptySeq;
1172
+ }
1173
+ if (!isSeq(integrations)) throw new InvalidIntegrationsTypeError();
1174
+ return integrations;
1175
+ }
1176
+ function getOrCreateIntegrationMetadata(doc, integrationMap) {
1177
+ const existingMetadata = integrationMap.get("metadata", true);
1178
+ if (isMap(existingMetadata)) return existingMetadata;
1179
+ const metadata = doc.createNode({});
1180
+ integrationMap.set("metadata", metadata);
1181
+ return metadata;
1182
+ }
1183
+ function updateIntegrationMetadataMap({ metadataMap, integrationId, integrationMetadata, secretPaths }) {
1184
+ const secrets = {};
1185
+ for (const [key, value] of Object.entries(integrationMetadata)) {
1186
+ if (value === void 0) continue;
1187
+ if (value === null) {
1188
+ metadataMap.set(key, null);
1189
+ continue;
1190
+ }
1191
+ if (!secretPaths.includes(key)) {
1192
+ metadataMap.set(key, value);
1193
+ continue;
1194
+ }
1195
+ const envVarName = extractEnvVarName(metadataMap.get(key)) ?? generateEnvVarName(integrationId, key);
1196
+ secrets[envVarName] = String(value);
1197
+ metadataMap.set(key, createEnvVarRef(envVarName));
1198
+ }
1199
+ return secrets;
1200
+ }
1201
+ /**
1202
+ * Update an existing integration entry in the document.
1203
+ * Preserves any comments or extra fields while updating known fields.
1204
+ * Extracts secrets and replaces them with env var references, preserving custom env var names.
1205
+ *
1206
+ * @returns Record of extracted secrets (envVarName -> secretValue)
1207
+ */
1208
+ function updateIntegrationInDocument(doc, integrationMap, integration) {
1209
+ const { id, name, type, metadata, federated_auth_method,...rest } = integration;
1210
+ integrationMap.set("id", id);
1211
+ integrationMap.set("name", name);
1212
+ integrationMap.set("type", type);
1213
+ const secretPaths = getSecretFieldPaths(type);
1214
+ const secrets = updateIntegrationMetadataMap({
1215
+ metadataMap: getOrCreateIntegrationMetadata(doc, integrationMap),
1216
+ integrationId: id,
1217
+ integrationMetadata: metadata,
1218
+ secretPaths
1219
+ });
1220
+ if (federated_auth_method !== void 0) integrationMap.set("federated_auth_method", federated_auth_method);
1221
+ else integrationMap.delete("federated_auth_method");
1222
+ return secrets;
1223
+ }
1224
+ /**
1225
+ * Add a new integration to the sequence.
1226
+ * Extracts secrets and replaces them with env var references.
1227
+ *
1228
+ * @returns Record of extracted secrets (envVarName -> secretValue)
1229
+ */
1230
+ function addIntegrationToSeq(doc, integrationsSeq, integration) {
1231
+ const secretPaths = getSecretFieldPaths(integration.type);
1232
+ const { metadata,...restIntegration } = integration;
1233
+ const integrationMap = doc.createNode(restIntegration);
1234
+ const metadataMap = doc.createNode({});
1235
+ const secrets = updateIntegrationMetadataMap({
1236
+ metadataMap,
1237
+ integrationId: integration.id,
1238
+ integrationMetadata: metadata,
1239
+ secretPaths
1240
+ });
1241
+ integrationMap.setIn(["metadata"], metadataMap);
1242
+ integrationsSeq.add(integrationMap);
1243
+ return secrets;
1244
+ }
1245
+ /**
1246
+ * Create a new Document with the schema comment.
1247
+ */
1248
+ function createNewDocument() {
1249
+ const doc = parseDocument("integrations: []\n", { version: "1.2" });
1250
+ doc.commentBefore = SCHEMA_COMMENT;
1251
+ const integrations = doc.get("integrations", true);
1252
+ if (isSeq(integrations)) integrations.flow = false;
1253
+ return doc;
1254
+ }
1255
+ /**
1256
+ * Merge processed integrations into the document.
1257
+ * Updates existing entries in-place (preserving comments) and adds new ones.
1258
+ * Extracts secrets and replaces them with env var references during the merge.
1259
+ * Preserves custom environment variable names from existing entries.
1260
+ *
1261
+ * @returns Object containing existing count and extracted secrets
1262
+ */
1263
+ function mergeProcessedIntegrations(doc, integrationsSeq, processedIntegrations) {
1264
+ const existingCount = integrationsSeq.items.length;
1265
+ let updatedCount = 0;
1266
+ let newCount = 0;
1267
+ const secrets = {};
1268
+ for (const databaseIntegration of processedIntegrations) {
1269
+ const existingIntegration = integrationsSeq.items.find((item) => {
1270
+ if (!isMap(item)) return false;
1271
+ return item.get("id") === databaseIntegration.id;
1272
+ });
1273
+ if (existingIntegration != null) {
1274
+ const extractedSecrets = updateIntegrationInDocument(doc, existingIntegration, databaseIntegration);
1275
+ Object.assign(secrets, extractedSecrets);
1276
+ updatedCount++;
1277
+ } else {
1278
+ const extractedSecrets = addIntegrationToSeq(doc, integrationsSeq, databaseIntegration);
1279
+ Object.assign(secrets, extractedSecrets);
1280
+ newCount++;
1281
+ }
1282
+ }
1283
+ return {
1284
+ secrets,
1285
+ stats: {
1286
+ existingCount,
1287
+ newCount,
1288
+ updatedCount
1289
+ }
1290
+ };
1291
+ }
1292
+ /**
1293
+ * Error thrown when an API integration fails schema validation during conversion.
1294
+ */
1295
+ var InvalidIntegrationError = class extends Error {
1296
+ integrationId;
1297
+ constructor(integrationId, message) {
1298
+ super(message);
1299
+ this.name = "InvalidIntegrationError";
1300
+ this.integrationId = integrationId;
1301
+ }
1302
+ };
1303
+ /**
1304
+ * Convert API integrations to DatabaseIntegrationConfig.
1305
+ * Validates each integration against the schema and collects errors for invalid ones.
1306
+ *
1307
+ * Shared by both `integrations pull` (via mergeApiIntegrationsIntoDocument) and `run` (for on-the-fly fetching).
1308
+ *
1309
+ * @param apiIntegrations - Integrations fetched from the API
1310
+ * @returns Object containing validated integrations and any validation errors
1311
+ */
1312
+ function convertApiIntegrations(apiIntegrations) {
1313
+ const integrations = [];
1314
+ const errors = [];
1315
+ for (const apiIntegration of apiIntegrations) {
1316
+ const config = databaseIntegrationConfigSchema.safeParse(apiIntegration);
1317
+ if (!config.success) {
1318
+ errors.push(new InvalidIntegrationError(apiIntegration.id, "Invalid integration returned by API."));
1319
+ continue;
1320
+ }
1321
+ integrations.push(config.data);
1322
+ }
1323
+ return {
1324
+ integrations,
1325
+ errors
1326
+ };
1327
+ }
1328
+ /**
1329
+ * Merge API integrations into an existing document (or create a new one).
1330
+ * Extracts secrets and replaces them with env var references during the merge.
1331
+ * Preserves custom environment variable names from existing entries.
1332
+ * Invalid or unsupported integrations are silently skipped.
1333
+ *
1334
+ * @param doc - The YAML document to merge into
1335
+ * @param apiIntegrations - Integrations fetched from the API
1336
+ * @returns The extracted secrets and merge statistics
1337
+ */
1338
+ function mergeApiIntegrationsIntoDocument(doc, apiIntegrations) {
1339
+ const integrationsSeq = getOrCreateIntegrationsFromDocument(doc);
1340
+ const skipped = [];
1341
+ return {
1342
+ ...mergeProcessedIntegrations(doc, integrationsSeq, apiIntegrations.reduce((acc, apiIntegration) => {
1343
+ const config = databaseIntegrationConfigSchema.safeParse(apiIntegration);
1344
+ if (!config.success) {
1345
+ skipped.push({
1346
+ id: apiIntegration.id,
1347
+ name: apiIntegration.name,
1348
+ type: apiIntegration.type,
1349
+ issues: config.error.issues
1350
+ });
1351
+ return acc;
1352
+ }
1353
+ acc.push(config.data);
1354
+ return acc;
1355
+ }, [])),
1356
+ skipped
1357
+ };
1358
+ }
1359
+
1360
+ //#endregion
1361
+ //#region src/loading/merge-into-yaml.ts
1362
+ /**
1363
+ * Merge API integrations into existing integrations YAML content (or create a new
1364
+ * document), returning the serialized YAML, the extracted secrets, and merge stats.
1365
+ *
1366
+ * This is a string-in / string-out convenience that mirrors what `deepnote
1367
+ * integrations pull` does to the YAML file — usable without touching the `yaml`
1368
+ * Document API. Callers persist `content` and `secrets` however they like (e.g.
1369
+ * the CLI writes files; the VS Code extension can write via `workspace.fs`).
1370
+ *
1371
+ * @param existingContent - Current YAML content, or `null` if the file doesn't exist yet
1372
+ * @param apiIntegrations - Integrations fetched from the API
1373
+ */
1374
+ function mergeApiIntegrationsIntoYaml(existingContent, apiIntegrations) {
1375
+ const doc = (existingContent != null ? parseIntegrationsDocument(existingContent) : null) ?? createNewDocument();
1376
+ const { secrets, stats, skipped } = mergeApiIntegrationsIntoDocument(doc, apiIntegrations);
1377
+ if (doc.commentBefore == null || !doc.commentBefore.includes("yaml-language-server")) doc.commentBefore = SCHEMA_COMMENT;
1378
+ return {
1379
+ content: serializeIntegrationsDocument(doc),
1380
+ secrets,
1381
+ stats,
1382
+ skipped
1383
+ };
1384
+ }
1385
+
1386
+ //#endregion
1387
+ //#region src/loading/parse-integrations.ts
1388
+ /**
1389
+ * Format Zod validation errors into ValidationIssue format.
1390
+ */
1391
+ function formatZodIssues(issues, pathPrefix) {
1392
+ return issues.map((issue) => ({
1393
+ path: [pathPrefix, ...issue.path].filter(Boolean).join("."),
1394
+ message: issue.message,
1395
+ code: issue.code
1396
+ }));
1397
+ }
1398
+ /**
1399
+ * Parse integrations YAML content gracefully.
1400
+ * Returns all valid integrations and collects validation issues for invalid ones.
1401
+ *
1402
+ * This is the content-accepting, environment-agnostic core (no filesystem or
1403
+ * `process.env` access) — callers supply the YAML text and the variable map used
1404
+ * to resolve `env:` references. The Node-only `parseIntegrationsFile` wraps this
1405
+ * to read from disk and default the map to `process.env`.
1406
+ *
1407
+ * @returns Object containing valid integrations and any validation issues
1408
+ */
1409
+ function parseIntegrations({ yaml, env = {} }) {
1410
+ const emptyIntegrations = [];
1411
+ const issues = [];
1412
+ let parsed;
1413
+ try {
1414
+ parsed = parseYaml(yaml);
1415
+ } catch (error) {
1416
+ const message = error instanceof Error ? error.message : String(error);
1417
+ issues.push({
1418
+ path: "",
1419
+ message: `Invalid YAML in integrations file: ${message}`,
1420
+ code: "yaml_parse_error"
1421
+ });
1422
+ return {
1423
+ integrations: emptyIntegrations,
1424
+ issues
1425
+ };
1426
+ }
1427
+ if (parsed === null || parsed === void 0) return {
1428
+ integrations: emptyIntegrations,
1429
+ issues
1430
+ };
1431
+ const fileResult = baseIntegrationsFileSchema.safeParse(parsed);
1432
+ if (!fileResult.success) {
1433
+ issues.push(...formatZodIssues(fileResult.error.issues, ""));
1434
+ return {
1435
+ integrations: emptyIntegrations,
1436
+ issues
1437
+ };
1438
+ }
1439
+ const entries = fileResult.data.integrations;
1440
+ const integrations = [];
1441
+ for (let i = 0; i < entries.length; i++) {
1442
+ const entry = entries[i];
1443
+ const pathPrefix = `integrations[${i}]`;
1444
+ const entryId = z$1.string().safeParse(entry.id).data;
1445
+ const integrationLabel = z$1.string().safeParse(entry.name).data || entryId;
1446
+ let resolvedEntry;
1447
+ try {
1448
+ resolvedEntry = resolveEnvVarRefsFromMap(entry, env);
1449
+ } catch (error) {
1450
+ if (error instanceof EnvVarResolutionError) {
1451
+ const context = integrationLabel ? `Integration "${integrationLabel}": ` : "";
1452
+ issues.push({
1453
+ path: error.path ? `${pathPrefix}.${error.path}` : pathPrefix,
1454
+ message: `${context}${error.message}`,
1455
+ code: "env_var_not_defined"
1456
+ });
1457
+ continue;
1458
+ }
1459
+ throw error;
1460
+ }
1461
+ const result = databaseIntegrationConfigSchema.safeParse(resolvedEntry);
1462
+ if (result.success) integrations.push(result.data);
1463
+ else {
1464
+ const formattedIssues = formatZodIssues(result.error.issues, pathPrefix);
1465
+ if (formattedIssues.length > 0 && integrationLabel) formattedIssues[0].message = `Integration "${integrationLabel}": ${formattedIssues[0].message}`;
1466
+ issues.push(...formattedIssues);
1467
+ }
1468
+ }
1469
+ return {
1470
+ integrations,
1471
+ issues
1472
+ };
1473
+ }
1474
+
1475
+ //#endregion
1476
+ export { ApiError, AwsAuthMethods, BUILTIN_INTEGRATIONS, BigQueryAuthMethods, BigQueryServiceAccountParseError, DEFAULT_API_URL, DEFAULT_ENV_FILE, DEFAULT_INTEGRATIONS_FILE, DatabaseAuthMethods, ENV_VAR_REF_PREFIX, EnvVarResolutionError, InvalidIntegrationError, InvalidIntegrationsTypeError, JSON_SCHEMA_URL, SCHEMA_COMMENT, SnowflakeAuthMethods, SpannerServiceAccountParseError, TrinoAuthMethods, addIntegrationToSeq, apiIntegrationSchema, apiResponseSchema, baseIntegrationsFileSchema, convertApiIntegrations, createEnvVarRef, createNewDocument, databaseIntegrationConfigSchema, databaseIntegrationTypes, databaseIntegrationTypesWithSslSupport, databaseMetadataSchemasByType, extractEnvVarName, federatedAuthMethods, fetchIntegrations, generateEnvVarName, getEnvironmentVariablesForIntegrations, getOrCreateIntegrationMetadata, getOrCreateIntegrationsFromDocument, getSecretFieldPaths, getSnowflakeFederatedAuthSqlAlchemyInput, getSqlAlchemyInput, getSqlEnvVarName, integrationsFileSchema, isDatabaseIntegrationType, isDatabaseIntegrationTypeWithSslSupport, isEnvVarRef, isFederatedAuthMetadata, isFederatedAuthMethod, isSqlIntegrationType, mergeApiIntegrationsIntoDocument, mergeApiIntegrationsIntoYaml, mergeProcessedIntegrations, parseEnvVarRef, parseIntegrations, parseIntegrationsDocument, resolveEnvVarRefsFromMap, serializeIntegrationsDocument, sqlIntegrationTypes, updateIntegrationInDocument, updateIntegrationMetadataMap };