@deepnote/database-integrations 1.6.0 → 1.7.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 +64 -39
- package/dist/index.d.cts +967 -943
- package/dist/index.d.ts +967 -943
- package/dist/index.js +55 -30
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -15,19 +16,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
16
|
}
|
|
16
17
|
return to;
|
|
17
18
|
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
19
20
|
value: mod,
|
|
20
21
|
enumerable: true
|
|
21
22
|
}) : target, mod));
|
|
22
|
-
|
|
23
23
|
//#endregion
|
|
24
24
|
let zod = require("zod");
|
|
25
|
-
zod = __toESM(zod);
|
|
25
|
+
zod = __toESM(zod, 1);
|
|
26
26
|
let yaml = require("yaml");
|
|
27
|
-
|
|
28
|
-
let __deepnote_blocks = require("@deepnote/blocks");
|
|
29
|
-
__deepnote_blocks = __toESM(__deepnote_blocks);
|
|
30
|
-
|
|
27
|
+
let _deepnote_blocks = require("@deepnote/blocks");
|
|
31
28
|
//#region src/sql-integration-auth-methods.ts
|
|
32
29
|
const AwsAuthMethods = {
|
|
33
30
|
AccessKeys: "access-keys",
|
|
@@ -68,7 +65,6 @@ function isFederatedAuthMethod(authMethod) {
|
|
|
68
65
|
function isFederatedAuthMetadata(metadata) {
|
|
69
66
|
return metadata.authMethod !== void 0 && isFederatedAuthMethod(metadata.authMethod);
|
|
70
67
|
}
|
|
71
|
-
|
|
72
68
|
//#endregion
|
|
73
69
|
//#region src/database-integration-metadata-schemas.ts
|
|
74
70
|
const athenaMetadataSchema = zod.z.object({
|
|
@@ -296,8 +292,6 @@ const pgsqlMetadataSchema = commonDatabaseSchema.extend({
|
|
|
296
292
|
caCertificateName: zod.z.string().optional(),
|
|
297
293
|
caCertificateText: zod.z.string().optional()
|
|
298
294
|
});
|
|
299
|
-
const materializeMetadataSchema = pgsqlMetadataSchema.extend({ cluster: zod.z.string() });
|
|
300
|
-
const sqlServerMetadataSchema = commonDatabaseSchema.extend({ port: zod.z.string() });
|
|
301
295
|
const databaseMetadataSchemasByType = {
|
|
302
296
|
"alloydb": alloydbMetadataSchema,
|
|
303
297
|
"athena": athenaMetadataSchema,
|
|
@@ -307,7 +301,7 @@ const databaseMetadataSchemasByType = {
|
|
|
307
301
|
"databricks": databricksMetadataSchema,
|
|
308
302
|
"dremio": dremioMetadataSchema,
|
|
309
303
|
"mariadb": mariadbMetadataSchema,
|
|
310
|
-
"materialize":
|
|
304
|
+
"materialize": pgsqlMetadataSchema.extend({ cluster: zod.z.string() }),
|
|
311
305
|
"mindsdb": mindsdbMetadataSchema,
|
|
312
306
|
"mongodb": mongodbMetadataSchema,
|
|
313
307
|
"mysql": mysqlMetadataSchema,
|
|
@@ -316,10 +310,9 @@ const databaseMetadataSchemasByType = {
|
|
|
316
310
|
"redshift": redshiftMetadataSchema,
|
|
317
311
|
"snowflake": snowflakeMetadataSchema,
|
|
318
312
|
"spanner": spannerMetadataSchema,
|
|
319
|
-
"sql-server":
|
|
313
|
+
"sql-server": commonDatabaseSchema.extend({ port: zod.z.string() }),
|
|
320
314
|
"trino": trinoMetadataSchema
|
|
321
315
|
};
|
|
322
|
-
|
|
323
316
|
//#endregion
|
|
324
317
|
//#region src/database-integration-config.ts
|
|
325
318
|
const commonIntegrationConfig = zod.default.object({
|
|
@@ -434,7 +427,6 @@ const databaseIntegrationConfigSchema = zod.default.discriminatedUnion("type", [
|
|
|
434
427
|
federated_auth_method: zod.default.enum(["trino-oauth", "password"]).optional().nullable()
|
|
435
428
|
})
|
|
436
429
|
]);
|
|
437
|
-
|
|
438
430
|
//#endregion
|
|
439
431
|
//#region src/snowflake-integration-env-vars.ts
|
|
440
432
|
/**
|
|
@@ -500,7 +492,6 @@ function createSqlAlchemyInputFromUrl(url, keyPair) {
|
|
|
500
492
|
param_style: "pyformat"
|
|
501
493
|
};
|
|
502
494
|
}
|
|
503
|
-
|
|
504
495
|
//#endregion
|
|
505
496
|
//#region src/database-integration-env-vars.ts
|
|
506
497
|
function getEnvironmentVariablesForIntegrations(integrations, params) {
|
|
@@ -865,7 +856,6 @@ function getSqlEnvVarName(integrationId) {
|
|
|
865
856
|
function assertNever(value) {
|
|
866
857
|
throw new Error(`Unexpected value: ${value}`);
|
|
867
858
|
}
|
|
868
|
-
|
|
869
859
|
//#endregion
|
|
870
860
|
//#region src/database-integration-types.ts
|
|
871
861
|
const sqlIntegrationTypes = [
|
|
@@ -910,7 +900,6 @@ function isSqlIntegrationType(type) {
|
|
|
910
900
|
function isDatabaseIntegrationTypeWithSslSupport(type) {
|
|
911
901
|
return databaseIntegrationTypesWithSslSupport.includes(type);
|
|
912
902
|
}
|
|
913
|
-
|
|
914
903
|
//#endregion
|
|
915
904
|
//#region src/loading/api-error.ts
|
|
916
905
|
/**
|
|
@@ -924,18 +913,31 @@ var ApiError = class extends Error {
|
|
|
924
913
|
this.statusCode = statusCode;
|
|
925
914
|
}
|
|
926
915
|
};
|
|
927
|
-
|
|
928
916
|
//#endregion
|
|
929
917
|
//#region src/loading/constants.ts
|
|
930
|
-
/** Built-in integrations that don't require external configuration. */
|
|
931
|
-
const BUILTIN_INTEGRATIONS = new Set(["deepnote-dataframe-sql", "pandas-dataframe"]);
|
|
918
|
+
/** Built-in integrations that don't require external configuration. Keys are canonical lowercase IDs. */
|
|
919
|
+
const BUILTIN_INTEGRATIONS = /* @__PURE__ */ new Set(["deepnote-dataframe-sql", "pandas-dataframe"]);
|
|
920
|
+
/**
|
|
921
|
+
* Return whether the given integration ID refers to a built-in integration.
|
|
922
|
+
*
|
|
923
|
+
* The comparison is case-insensitive: built-in IDs are stored as canonical
|
|
924
|
+
* lowercase strings in {@link BUILTIN_INTEGRATIONS}, and SQL block metadata may
|
|
925
|
+
* reference them in any casing (e.g. `Pandas-DataFrame`). This mirrors the
|
|
926
|
+
* case-insensitive env-var derivation in `getSqlEnvVarName`, so a built-in is
|
|
927
|
+
* recognized regardless of how a notebook cased its `sql_integration_id`.
|
|
928
|
+
*
|
|
929
|
+
* @param integrationId - The integration ID from SQL block metadata.
|
|
930
|
+
* @returns `true` when the ID matches a built-in integration regardless of casing.
|
|
931
|
+
*/
|
|
932
|
+
function isBuiltinIntegration(integrationId) {
|
|
933
|
+
return BUILTIN_INTEGRATIONS.has(integrationId.toLowerCase());
|
|
934
|
+
}
|
|
932
935
|
/** Default `.env` file name for storing integration secrets. */
|
|
933
936
|
const DEFAULT_ENV_FILE = ".env";
|
|
934
937
|
/** Default integrations file name. */
|
|
935
938
|
const DEFAULT_INTEGRATIONS_FILE = ".deepnote.env.yaml";
|
|
936
939
|
/** Default Deepnote API base URL. */
|
|
937
940
|
const DEFAULT_API_URL = "https://api.deepnote.com";
|
|
938
|
-
|
|
939
941
|
//#endregion
|
|
940
942
|
//#region src/loading/env-var-refs.ts
|
|
941
943
|
const ENV_VAR_REF_PREFIX = "env:";
|
|
@@ -944,7 +946,7 @@ function generateEnvVarName(integrationId, fieldPath) {
|
|
|
944
946
|
}
|
|
945
947
|
function parseEnvVarRef(value) {
|
|
946
948
|
if (typeof value !== "string") return null;
|
|
947
|
-
if (!value.startsWith(
|
|
949
|
+
if (!value.startsWith("env:")) return null;
|
|
948
950
|
const varName = value.slice(4);
|
|
949
951
|
if (!varName) return null;
|
|
950
952
|
return {
|
|
@@ -1007,7 +1009,6 @@ function resolveEnvVarRefsFromMap(obj, vars, currentPath) {
|
|
|
1007
1009
|
}
|
|
1008
1010
|
return obj;
|
|
1009
1011
|
}
|
|
1010
|
-
|
|
1011
1012
|
//#endregion
|
|
1012
1013
|
//#region src/loading/fetch-integrations.ts
|
|
1013
1014
|
/**
|
|
@@ -1038,14 +1039,17 @@ function trimTrailingSlash(url) {
|
|
|
1038
1039
|
*
|
|
1039
1040
|
* @param baseUrl - The base URL of the Deepnote API
|
|
1040
1041
|
* @param token - The authentication token
|
|
1041
|
-
* @param integrationIds - Optional list of integration
|
|
1042
|
+
* @param integrationIds - Optional list of integration UUIDs to fetch. When provided, only these integrations are returned.
|
|
1042
1043
|
* @returns Array of integrations from the API
|
|
1043
1044
|
* @throws ApiError if the request fails
|
|
1044
1045
|
*/
|
|
1045
1046
|
async function fetchIntegrations(baseUrl, token, integrationIds) {
|
|
1046
1047
|
const endpoint = new URL(`${trimTrailingSlash(baseUrl)}/v2/integrations`);
|
|
1047
1048
|
endpoint.searchParams.set("includeMetadata", "true");
|
|
1048
|
-
if (integrationIds && integrationIds.length > 0)
|
|
1049
|
+
if (integrationIds && integrationIds.length > 0) {
|
|
1050
|
+
const normalizedIntegrationIds = new Set(integrationIds.map((id) => id.toLowerCase()));
|
|
1051
|
+
endpoint.searchParams.set("integrationIds", Array.from(normalizedIntegrationIds).join(","));
|
|
1052
|
+
}
|
|
1049
1053
|
const url = endpoint.toString();
|
|
1050
1054
|
const response = await fetch(url, {
|
|
1051
1055
|
method: "GET",
|
|
@@ -1065,21 +1069,38 @@ async function fetchIntegrations(baseUrl, token, integrationIds) {
|
|
|
1065
1069
|
if (!parseResult.success) throw new Error(`Invalid API response: ${parseResult.error.message}`);
|
|
1066
1070
|
return parseResult.data.integrations;
|
|
1067
1071
|
}
|
|
1068
|
-
|
|
1069
1072
|
//#endregion
|
|
1070
1073
|
//#region src/loading/integrations-document.ts
|
|
1071
1074
|
/**
|
|
1075
|
+
* Error thrown when integrations YAML content cannot be parsed.
|
|
1076
|
+
*/
|
|
1077
|
+
var IntegrationsYamlParseError = class extends Error {
|
|
1078
|
+
/** The underlying parse errors reported by the `yaml` library. */
|
|
1079
|
+
errors;
|
|
1080
|
+
constructor(errors) {
|
|
1081
|
+
super(`Failed to parse integrations YAML: ${errors[0]?.message ?? "unknown parse error"}`);
|
|
1082
|
+
this.name = "IntegrationsYamlParseError";
|
|
1083
|
+
this.errors = errors;
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
/**
|
|
1072
1087
|
* Parse integrations YAML content into a mutable `yaml` Document that preserves
|
|
1073
1088
|
* comments and formatting. Returns `null` for empty content.
|
|
1074
1089
|
*
|
|
1075
1090
|
* This is the content-accepting counterpart of the Node-only `readIntegrationsDocument`.
|
|
1091
|
+
*
|
|
1092
|
+
* @throws {IntegrationsYamlParseError} If the content is not valid YAML. Malformed
|
|
1093
|
+
* content is rejected here rather than at serialization time, where `yaml` would
|
|
1094
|
+
* otherwise fail with an opaque "Document with errors cannot be stringified".
|
|
1076
1095
|
*/
|
|
1077
1096
|
function parseIntegrationsDocument(content) {
|
|
1078
1097
|
if (!content.trim()) return null;
|
|
1079
|
-
|
|
1098
|
+
const doc = (0, yaml.parseDocument)(content, {
|
|
1080
1099
|
strict: true,
|
|
1081
1100
|
version: "1.2"
|
|
1082
1101
|
});
|
|
1102
|
+
if (doc.errors.length > 0) throw new IntegrationsYamlParseError(doc.errors);
|
|
1103
|
+
return doc;
|
|
1083
1104
|
}
|
|
1084
1105
|
/**
|
|
1085
1106
|
* Serialize an integrations Document back to YAML text, preserving comments and
|
|
@@ -1088,7 +1109,6 @@ function parseIntegrationsDocument(content) {
|
|
|
1088
1109
|
function serializeIntegrationsDocument(doc) {
|
|
1089
1110
|
return doc.toString({ lineWidth: 0 });
|
|
1090
1111
|
}
|
|
1091
|
-
|
|
1092
1112
|
//#endregion
|
|
1093
1113
|
//#region src/loading/integrations-file-schema.ts
|
|
1094
1114
|
/**
|
|
@@ -1109,7 +1129,6 @@ function serializeIntegrationsDocument(doc) {
|
|
|
1109
1129
|
*/
|
|
1110
1130
|
const baseIntegrationsFileSchema = zod.z.object({ integrations: zod.z.array(zod.z.record(zod.z.unknown())).optional().default([]) });
|
|
1111
1131
|
const integrationsFileSchema = zod.z.object({ integrations: zod.z.array(databaseIntegrationConfigSchema) });
|
|
1112
|
-
|
|
1113
1132
|
//#endregion
|
|
1114
1133
|
//#region src/secret-field-paths.ts
|
|
1115
1134
|
/**
|
|
@@ -1168,7 +1187,6 @@ const SECRET_PATHS = {
|
|
|
1168
1187
|
function getSecretFieldPaths(type) {
|
|
1169
1188
|
return SECRET_PATHS[type] ?? [];
|
|
1170
1189
|
}
|
|
1171
|
-
|
|
1172
1190
|
//#endregion
|
|
1173
1191
|
//#region src/loading/merge-integrations.ts
|
|
1174
1192
|
/**
|
|
@@ -1238,7 +1256,7 @@ function updateIntegrationMetadataMap({ metadataMap, integrationId, integrationM
|
|
|
1238
1256
|
* @returns Record of extracted secrets (envVarName -> secretValue)
|
|
1239
1257
|
*/
|
|
1240
1258
|
function updateIntegrationInDocument(doc, integrationMap, integration) {
|
|
1241
|
-
const { id, name, type, metadata, federated_auth_method
|
|
1259
|
+
const { id, name, type, metadata, federated_auth_method, ...rest } = integration;
|
|
1242
1260
|
integrationMap.set("id", id);
|
|
1243
1261
|
integrationMap.set("name", name);
|
|
1244
1262
|
integrationMap.set("type", type);
|
|
@@ -1261,7 +1279,7 @@ function updateIntegrationInDocument(doc, integrationMap, integration) {
|
|
|
1261
1279
|
*/
|
|
1262
1280
|
function addIntegrationToSeq(doc, integrationsSeq, integration) {
|
|
1263
1281
|
const secretPaths = getSecretFieldPaths(integration.type);
|
|
1264
|
-
const { metadata
|
|
1282
|
+
const { metadata, ...restIntegration } = integration;
|
|
1265
1283
|
const integrationMap = doc.createNode(restIntegration);
|
|
1266
1284
|
const metadataMap = doc.createNode({});
|
|
1267
1285
|
const secrets = updateIntegrationMetadataMap({
|
|
@@ -1388,7 +1406,6 @@ function mergeApiIntegrationsIntoDocument(doc, apiIntegrations) {
|
|
|
1388
1406
|
skipped
|
|
1389
1407
|
};
|
|
1390
1408
|
}
|
|
1391
|
-
|
|
1392
1409
|
//#endregion
|
|
1393
1410
|
//#region src/loading/merge-into-yaml.ts
|
|
1394
1411
|
/**
|
|
@@ -1402,6 +1419,14 @@ function mergeApiIntegrationsIntoDocument(doc, apiIntegrations) {
|
|
|
1402
1419
|
*
|
|
1403
1420
|
* @param existingContent - Current YAML content, or `null` if the file doesn't exist yet
|
|
1404
1421
|
* @param apiIntegrations - Integrations fetched from the API
|
|
1422
|
+
*
|
|
1423
|
+
* @throws {IntegrationsYamlParseError} If `existingContent` is not valid YAML (for
|
|
1424
|
+
* example, unresolved git merge conflict markers). Callers that want to rebuild the
|
|
1425
|
+
* file from scratch instead of surfacing the error can catch it and re-run with
|
|
1426
|
+
* `mergeApiIntegrationsIntoYaml(null, apiIntegrations)` — note this discards the
|
|
1427
|
+
* existing content, including any local-only integrations and comments.
|
|
1428
|
+
* @throws {InvalidIntegrationsTypeError} If the existing `integrations` property is
|
|
1429
|
+
* present but is not a list.
|
|
1405
1430
|
*/
|
|
1406
1431
|
function mergeApiIntegrationsIntoYaml(existingContent, apiIntegrations) {
|
|
1407
1432
|
const doc = (existingContent != null ? parseIntegrationsDocument(existingContent) : null) ?? createNewDocument();
|
|
@@ -1414,7 +1439,6 @@ function mergeApiIntegrationsIntoYaml(existingContent, apiIntegrations) {
|
|
|
1414
1439
|
skipped
|
|
1415
1440
|
};
|
|
1416
1441
|
}
|
|
1417
|
-
|
|
1418
1442
|
//#endregion
|
|
1419
1443
|
//#region src/loading/parse-integrations.ts
|
|
1420
1444
|
/**
|
|
@@ -1438,12 +1462,12 @@ function formatZodIssues(issues, pathPrefix) {
|
|
|
1438
1462
|
*
|
|
1439
1463
|
* @returns Object containing valid integrations and any validation issues
|
|
1440
1464
|
*/
|
|
1441
|
-
function parseIntegrations({ yaml
|
|
1465
|
+
function parseIntegrations({ yaml, env = {} }) {
|
|
1442
1466
|
const emptyIntegrations = [];
|
|
1443
1467
|
const issues = [];
|
|
1444
1468
|
let parsed;
|
|
1445
1469
|
try {
|
|
1446
|
-
parsed = (0,
|
|
1470
|
+
parsed = (0, _deepnote_blocks.parseYaml)(yaml);
|
|
1447
1471
|
} catch (error) {
|
|
1448
1472
|
const message = error instanceof Error ? error.message : String(error);
|
|
1449
1473
|
issues.push({
|
|
@@ -1503,7 +1527,6 @@ function parseIntegrations({ yaml: yaml$1, env = {} }) {
|
|
|
1503
1527
|
issues
|
|
1504
1528
|
};
|
|
1505
1529
|
}
|
|
1506
|
-
|
|
1507
1530
|
//#endregion
|
|
1508
1531
|
exports.ApiError = ApiError;
|
|
1509
1532
|
exports.AwsAuthMethods = AwsAuthMethods;
|
|
@@ -1516,6 +1539,7 @@ exports.DEFAULT_INTEGRATIONS_FILE = DEFAULT_INTEGRATIONS_FILE;
|
|
|
1516
1539
|
exports.DatabaseAuthMethods = DatabaseAuthMethods;
|
|
1517
1540
|
exports.ENV_VAR_REF_PREFIX = ENV_VAR_REF_PREFIX;
|
|
1518
1541
|
exports.EnvVarResolutionError = EnvVarResolutionError;
|
|
1542
|
+
exports.IntegrationsYamlParseError = IntegrationsYamlParseError;
|
|
1519
1543
|
exports.InvalidIntegrationError = InvalidIntegrationError;
|
|
1520
1544
|
exports.InvalidIntegrationsTypeError = InvalidIntegrationsTypeError;
|
|
1521
1545
|
exports.JSON_SCHEMA_URL = JSON_SCHEMA_URL;
|
|
@@ -1546,6 +1570,7 @@ exports.getSnowflakeFederatedAuthSqlAlchemyInput = getSnowflakeFederatedAuthSqlA
|
|
|
1546
1570
|
exports.getSqlAlchemyInput = getSqlAlchemyInput;
|
|
1547
1571
|
exports.getSqlEnvVarName = getSqlEnvVarName;
|
|
1548
1572
|
exports.integrationsFileSchema = integrationsFileSchema;
|
|
1573
|
+
exports.isBuiltinIntegration = isBuiltinIntegration;
|
|
1549
1574
|
exports.isDatabaseIntegrationType = isDatabaseIntegrationType;
|
|
1550
1575
|
exports.isDatabaseIntegrationTypeWithSslSupport = isDatabaseIntegrationTypeWithSslSupport;
|
|
1551
1576
|
exports.isEnvVarRef = isEnvVarRef;
|
|
@@ -1562,4 +1587,4 @@ exports.resolveEnvVarRefsFromMap = resolveEnvVarRefsFromMap;
|
|
|
1562
1587
|
exports.serializeIntegrationsDocument = serializeIntegrationsDocument;
|
|
1563
1588
|
exports.sqlIntegrationTypes = sqlIntegrationTypes;
|
|
1564
1589
|
exports.updateIntegrationInDocument = updateIntegrationInDocument;
|
|
1565
|
-
exports.updateIntegrationMetadataMap = updateIntegrationMetadataMap;
|
|
1590
|
+
exports.updateIntegrationMetadataMap = updateIntegrationMetadataMap;
|