@deepnote/database-integrations 1.7.1 → 2.1.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 +90 -67
- package/dist/index.d.cts +201 -4718
- package/dist/index.d.ts +201 -4718
- package/dist/index.js +87 -66
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -23,8 +23,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
let zod = require("zod");
|
|
25
25
|
zod = __toESM(zod, 1);
|
|
26
|
-
let yaml = require("yaml");
|
|
27
26
|
let _deepnote_blocks = require("@deepnote/blocks");
|
|
27
|
+
let yaml = require("yaml");
|
|
28
28
|
//#region src/sql-integration-auth-methods.ts
|
|
29
29
|
const AwsAuthMethods = {
|
|
30
30
|
AccessKeys: "access-keys",
|
|
@@ -428,6 +428,73 @@ const databaseIntegrationConfigSchema = zod.default.discriminatedUnion("type", [
|
|
|
428
428
|
})
|
|
429
429
|
]);
|
|
430
430
|
//#endregion
|
|
431
|
+
//#region src/secret-field-paths.ts
|
|
432
|
+
/**
|
|
433
|
+
* All secret fields for each integration type.
|
|
434
|
+
* This includes all possible secret fields regardless of auth method.
|
|
435
|
+
*
|
|
436
|
+
* Note: For integrations with multiple auth methods (e.g., snowflake, bigquery),
|
|
437
|
+
* this includes all secret fields from all auth variants.
|
|
438
|
+
*/
|
|
439
|
+
const SECRET_PATHS = {
|
|
440
|
+
alloydb: ["password", "caCertificateText"],
|
|
441
|
+
mariadb: ["password", "caCertificateText"],
|
|
442
|
+
materialize: ["password", "caCertificateText"],
|
|
443
|
+
mindsdb: ["password", "caCertificateText"],
|
|
444
|
+
mysql: ["password", "caCertificateText"],
|
|
445
|
+
pgsql: ["password", "caCertificateText"],
|
|
446
|
+
"sql-server": ["password"],
|
|
447
|
+
clickhouse: ["password", "caCertificateText"],
|
|
448
|
+
databricks: ["token"],
|
|
449
|
+
dremio: ["token"],
|
|
450
|
+
athena: ["secret_access_key"],
|
|
451
|
+
spanner: ["service_account"],
|
|
452
|
+
"cloud-sql": ["service_account"],
|
|
453
|
+
mongodb: [
|
|
454
|
+
"password",
|
|
455
|
+
"connection_string",
|
|
456
|
+
"rawConnectionString",
|
|
457
|
+
"caCertificateText"
|
|
458
|
+
],
|
|
459
|
+
"pandas-dataframe": [],
|
|
460
|
+
"big-query": ["service_account", "clientSecret"],
|
|
461
|
+
snowflake: [
|
|
462
|
+
"password",
|
|
463
|
+
"clientSecret",
|
|
464
|
+
"privateKey",
|
|
465
|
+
"privateKeyPassphrase",
|
|
466
|
+
"dbtServiceToken"
|
|
467
|
+
],
|
|
468
|
+
redshift: ["password", "caCertificateText"],
|
|
469
|
+
trino: [
|
|
470
|
+
"password",
|
|
471
|
+
"clientSecret",
|
|
472
|
+
"caCertificateText"
|
|
473
|
+
]
|
|
474
|
+
};
|
|
475
|
+
/**
|
|
476
|
+
* Get the list of secret field paths for a given integration type.
|
|
477
|
+
*
|
|
478
|
+
* @param type - The integration type (e.g., 'pgsql', 'snowflake')
|
|
479
|
+
* @returns Array of field names that contain secrets
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* getSecretFieldPaths('pgsql') // => ['password', 'caCertificateText']
|
|
483
|
+
* getSecretFieldPaths('snowflake') // => ['password', 'clientSecret', 'privateKey', 'privateKeyPassphrase', 'dbtServiceToken']
|
|
484
|
+
*/
|
|
485
|
+
function getSecretFieldPaths(type) {
|
|
486
|
+
return SECRET_PATHS[type] ?? [];
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Whether `key` is a secret field of an integration whose `metadata.authMethod` is federated.
|
|
490
|
+
* Such integrations authenticate each user with their own identity, so the value never needs
|
|
491
|
+
* to reach notebook code.
|
|
492
|
+
*/
|
|
493
|
+
function isFederatedAuthSecretField(type, metadata, key) {
|
|
494
|
+
const { authMethod } = metadata;
|
|
495
|
+
return typeof authMethod === "string" && isFederatedAuthMethod(authMethod) && getSecretFieldPaths(type).includes(key);
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
431
498
|
//#region src/snowflake-integration-env-vars.ts
|
|
432
499
|
/**
|
|
433
500
|
* Build a URL with path and query parameters using native URL API
|
|
@@ -498,9 +565,9 @@ function getEnvironmentVariablesForIntegrations(integrations, params) {
|
|
|
498
565
|
const envVars = [];
|
|
499
566
|
const errors = [];
|
|
500
567
|
integrations.forEach((integration) => {
|
|
501
|
-
const namePrefix = convertToEnvironmentVariableName(integration.name);
|
|
568
|
+
const namePrefix = (0, _deepnote_blocks.convertToEnvironmentVariableName)(integration.name);
|
|
502
569
|
const envVarsForThisIntegration = Object.entries(integration.metadata).filter(([key]) => {
|
|
503
|
-
return key !== "caCertificateText";
|
|
570
|
+
return key !== "caCertificateText" && !isFederatedAuthSecretField(integration.type, integration.metadata, key);
|
|
504
571
|
}).map(([key, rawValue]) => {
|
|
505
572
|
const name = `${namePrefix}_${key.toUpperCase()}`;
|
|
506
573
|
const value = String(rawValue);
|
|
@@ -798,6 +865,21 @@ const getBigQuerySqlAlchemyInput = (metadata) => {
|
|
|
798
865
|
throw new BigQueryServiceAccountParseError("Failed to parse bigquery service account, returning empty environment variable.", { cause: error instanceof Error ? error : new Error(String(error)) });
|
|
799
866
|
}
|
|
800
867
|
};
|
|
868
|
+
/**
|
|
869
|
+
* @returns sql alchemy input for a BigQuery integration authenticated via Google OAuth, given an
|
|
870
|
+
* access token minted by the caller. `user_supplied_client=true` tells the runtime to build its
|
|
871
|
+
* BigQuery client from `access_token` / `project` instead of a service account.
|
|
872
|
+
*/
|
|
873
|
+
function getBigQueryOAuthSqlAlchemyInput(metadata, accessToken) {
|
|
874
|
+
return {
|
|
875
|
+
url: "bigquery://?user_supplied_client=true",
|
|
876
|
+
params: {
|
|
877
|
+
access_token: accessToken,
|
|
878
|
+
project: metadata.project
|
|
879
|
+
},
|
|
880
|
+
param_style: "pyformat"
|
|
881
|
+
};
|
|
882
|
+
}
|
|
801
883
|
var SpannerServiceAccountParseError = class extends Error {
|
|
802
884
|
cause;
|
|
803
885
|
constructor(message, params) {
|
|
@@ -847,11 +929,8 @@ const getMySqlSqlAlchemyInput = (integrationId, projectRootDirectory, { user, pa
|
|
|
847
929
|
function getCACertificatePath({ projectRoot, integrationId, caCertificateName }) {
|
|
848
930
|
return `${projectRoot}/.deepnote/${integrationId}/${caCertificateName}`;
|
|
849
931
|
}
|
|
850
|
-
function convertToEnvironmentVariableName(str) {
|
|
851
|
-
return (/^\d/.test(str) ? `_${str}` : str).toUpperCase().replace(/[^\w]/g, "_");
|
|
852
|
-
}
|
|
853
932
|
function getSqlEnvVarName(integrationId) {
|
|
854
|
-
return convertToEnvironmentVariableName(`SQL_${integrationId}`);
|
|
933
|
+
return (0, _deepnote_blocks.convertToEnvironmentVariableName)(`SQL_${integrationId}`);
|
|
855
934
|
}
|
|
856
935
|
function assertNever(value) {
|
|
857
936
|
throw new Error(`Unexpected value: ${value}`);
|
|
@@ -1018,7 +1097,7 @@ const apiIntegrationSchema = zod.z.object({
|
|
|
1018
1097
|
id: zod.z.string(),
|
|
1019
1098
|
name: zod.z.string(),
|
|
1020
1099
|
type: zod.z.string(),
|
|
1021
|
-
metadata: zod.z.unknown(),
|
|
1100
|
+
metadata: zod.z.unknown().optional(),
|
|
1022
1101
|
is_public: zod.z.boolean().nullish(),
|
|
1023
1102
|
created_at: zod.z.string().nullish(),
|
|
1024
1103
|
updated_at: zod.z.string().nullish(),
|
|
@@ -1127,67 +1206,9 @@ function serializeIntegrationsDocument(doc) {
|
|
|
1127
1206
|
* ...
|
|
1128
1207
|
* ```
|
|
1129
1208
|
*/
|
|
1130
|
-
const baseIntegrationsFileSchema = zod.z.object({ integrations: zod.z.array(zod.z.record(zod.z.unknown())).optional().default([]) });
|
|
1209
|
+
const baseIntegrationsFileSchema = zod.z.object({ integrations: zod.z.array(zod.z.record(zod.z.string(), zod.z.unknown())).optional().default([]) });
|
|
1131
1210
|
const integrationsFileSchema = zod.z.object({ integrations: zod.z.array(databaseIntegrationConfigSchema) });
|
|
1132
1211
|
//#endregion
|
|
1133
|
-
//#region src/secret-field-paths.ts
|
|
1134
|
-
/**
|
|
1135
|
-
* All secret fields for each integration type.
|
|
1136
|
-
* This includes all possible secret fields regardless of auth method.
|
|
1137
|
-
*
|
|
1138
|
-
* Note: For integrations with multiple auth methods (e.g., snowflake, bigquery),
|
|
1139
|
-
* this includes all secret fields from all auth variants.
|
|
1140
|
-
*/
|
|
1141
|
-
const SECRET_PATHS = {
|
|
1142
|
-
alloydb: ["password", "caCertificateText"],
|
|
1143
|
-
mariadb: ["password", "caCertificateText"],
|
|
1144
|
-
materialize: ["password", "caCertificateText"],
|
|
1145
|
-
mindsdb: ["password", "caCertificateText"],
|
|
1146
|
-
mysql: ["password", "caCertificateText"],
|
|
1147
|
-
pgsql: ["password", "caCertificateText"],
|
|
1148
|
-
"sql-server": ["password"],
|
|
1149
|
-
clickhouse: ["password", "caCertificateText"],
|
|
1150
|
-
databricks: ["token"],
|
|
1151
|
-
dremio: ["token"],
|
|
1152
|
-
athena: ["secret_access_key"],
|
|
1153
|
-
spanner: ["service_account"],
|
|
1154
|
-
"cloud-sql": ["service_account"],
|
|
1155
|
-
mongodb: [
|
|
1156
|
-
"password",
|
|
1157
|
-
"connection_string",
|
|
1158
|
-
"rawConnectionString",
|
|
1159
|
-
"caCertificateText"
|
|
1160
|
-
],
|
|
1161
|
-
"pandas-dataframe": [],
|
|
1162
|
-
"big-query": ["service_account", "clientSecret"],
|
|
1163
|
-
snowflake: [
|
|
1164
|
-
"password",
|
|
1165
|
-
"clientSecret",
|
|
1166
|
-
"privateKey",
|
|
1167
|
-
"privateKeyPassphrase",
|
|
1168
|
-
"dbtServiceToken"
|
|
1169
|
-
],
|
|
1170
|
-
redshift: ["password", "caCertificateText"],
|
|
1171
|
-
trino: [
|
|
1172
|
-
"password",
|
|
1173
|
-
"clientSecret",
|
|
1174
|
-
"caCertificateText"
|
|
1175
|
-
]
|
|
1176
|
-
};
|
|
1177
|
-
/**
|
|
1178
|
-
* Get the list of secret field paths for a given integration type.
|
|
1179
|
-
*
|
|
1180
|
-
* @param type - The integration type (e.g., 'pgsql', 'snowflake')
|
|
1181
|
-
* @returns Array of field names that contain secrets
|
|
1182
|
-
*
|
|
1183
|
-
* @example
|
|
1184
|
-
* getSecretFieldPaths('pgsql') // => ['password', 'caCertificateText']
|
|
1185
|
-
* getSecretFieldPaths('snowflake') // => ['password', 'clientSecret', 'privateKey', 'privateKeyPassphrase', 'dbtServiceToken']
|
|
1186
|
-
*/
|
|
1187
|
-
function getSecretFieldPaths(type) {
|
|
1188
|
-
return SECRET_PATHS[type] ?? [];
|
|
1189
|
-
}
|
|
1190
|
-
//#endregion
|
|
1191
1212
|
//#region src/loading/merge-integrations.ts
|
|
1192
1213
|
/**
|
|
1193
1214
|
* JSON schema URL for the integrations file.
|
|
@@ -1562,6 +1583,7 @@ exports.extractEnvVarName = extractEnvVarName;
|
|
|
1562
1583
|
exports.federatedAuthMethods = federatedAuthMethods;
|
|
1563
1584
|
exports.fetchIntegrations = fetchIntegrations;
|
|
1564
1585
|
exports.generateEnvVarName = generateEnvVarName;
|
|
1586
|
+
exports.getBigQueryOAuthSqlAlchemyInput = getBigQueryOAuthSqlAlchemyInput;
|
|
1565
1587
|
exports.getEnvironmentVariablesForIntegrations = getEnvironmentVariablesForIntegrations;
|
|
1566
1588
|
exports.getOrCreateIntegrationMetadata = getOrCreateIntegrationMetadata;
|
|
1567
1589
|
exports.getOrCreateIntegrationsFromDocument = getOrCreateIntegrationsFromDocument;
|
|
@@ -1576,6 +1598,7 @@ exports.isDatabaseIntegrationTypeWithSslSupport = isDatabaseIntegrationTypeWithS
|
|
|
1576
1598
|
exports.isEnvVarRef = isEnvVarRef;
|
|
1577
1599
|
exports.isFederatedAuthMetadata = isFederatedAuthMetadata;
|
|
1578
1600
|
exports.isFederatedAuthMethod = isFederatedAuthMethod;
|
|
1601
|
+
exports.isFederatedAuthSecretField = isFederatedAuthSecretField;
|
|
1579
1602
|
exports.isSqlIntegrationType = isSqlIntegrationType;
|
|
1580
1603
|
exports.mergeApiIntegrationsIntoDocument = mergeApiIntegrationsIntoDocument;
|
|
1581
1604
|
exports.mergeApiIntegrationsIntoYaml = mergeApiIntegrationsIntoYaml;
|