@malloy-publisher/server 0.10.4 → 0.10.5
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/app/api-doc.yaml
CHANGED
|
@@ -6685,8 +6685,11 @@ components:
|
|
|
6685
6685
|
`sqlSource` answer 400 for anything else (another statement type, or
|
|
6686
6686
|
more than one statement), and `sqlTemporaryTable` answers 400 always.
|
|
6687
6687
|
This is a rule on statements, not on what a SELECT reads: that is
|
|
6688
|
-
bounded by the session's storage secret
|
|
6689
|
-
|
|
6688
|
+
bounded by the catalog role and by the session's storage secret,
|
|
6689
|
+
which on a managed connection attached read-only is scoped to the
|
|
6690
|
+
`main` schema's recorded path, so a SELECT reads only that schema's
|
|
6691
|
+
files; another schema's files, and any other object in the bucket,
|
|
6692
|
+
are unsigned (403). Absent or false is the pre-existing behavior.
|
|
6690
6693
|
fingerprint:
|
|
6691
6694
|
type: string
|
|
6692
6695
|
description: >
|
|
@@ -7157,7 +7160,11 @@ components:
|
|
|
7157
7160
|
every attach uses the data path the catalog recorded at its
|
|
7158
7161
|
creation, and no attach ever creates a catalog: the shape for a
|
|
7159
7162
|
catalog created elsewhere, through the admin API
|
|
7160
|
-
(admin-api-doc.yaml) or by another tool.
|
|
7163
|
+
(admin-api-doc.yaml) or by another tool. Either way the storage
|
|
7164
|
+
secret is scoped to the data path, the given one or the
|
|
7165
|
+
recorded one: a read of any other object through this
|
|
7166
|
+
connection is unsigned, and on S3 the host's AWS_* environment
|
|
7167
|
+
never signs it either. A catalog with neither is not attached.
|
|
7161
7168
|
s3Connection:
|
|
7162
7169
|
$ref: "#/components/schemas/S3Connection"
|
|
7163
7170
|
description: AWS S3 connection configuration for data storage
|
|
Binary file
|
package/dist/instrumentation.mjs
CHANGED
|
@@ -164831,7 +164831,7 @@ var init_telemetry = __esm(() => {
|
|
|
164831
164831
|
});
|
|
164832
164832
|
|
|
164833
164833
|
// package.json
|
|
164834
|
-
var version = "0.10.
|
|
164834
|
+
var version = "0.10.5";
|
|
164835
164835
|
var init_package = () => {};
|
|
164836
164836
|
|
|
164837
164837
|
// src/version.ts
|
package/dist/server.mjs
CHANGED
|
@@ -164832,7 +164832,7 @@ var init_telemetry = __esm(() => {
|
|
|
164832
164832
|
});
|
|
164833
164833
|
|
|
164834
164834
|
// package.json
|
|
164835
|
-
var version = "0.10.
|
|
164835
|
+
var version = "0.10.5";
|
|
164836
164836
|
var init_package = () => {};
|
|
164837
164837
|
|
|
164838
164838
|
// src/version.ts
|
|
@@ -268349,7 +268349,7 @@ var require_bcrypt_pbkdf = __commonJS((exports, module) => {
|
|
|
268349
268349
|
|
|
268350
268350
|
// ../../node_modules/cpu-features/build/Release/cpufeatures.node
|
|
268351
268351
|
var require_cpufeatures = __commonJS((exports, module) => {
|
|
268352
|
-
module.exports = __require("./cpufeatures-
|
|
268352
|
+
module.exports = __require("./cpufeatures-gknxfsk5.node");
|
|
268353
268353
|
});
|
|
268354
268354
|
|
|
268355
268355
|
// ../../node_modules/cpu-features/lib/index.js
|
|
@@ -268960,6 +268960,11 @@ var require_utils93 = __commonJS((exports, module) => {
|
|
|
268960
268960
|
};
|
|
268961
268961
|
});
|
|
268962
268962
|
|
|
268963
|
+
// ../../node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
|
|
268964
|
+
var require_sshcrypto = __commonJS((exports, module) => {
|
|
268965
|
+
module.exports = __require("./sshcrypto-a4xyg5e8.node");
|
|
268966
|
+
});
|
|
268967
|
+
|
|
268963
268968
|
// ../../node_modules/ssh2/lib/protocol/crypto/poly1305.js
|
|
268964
268969
|
var require_poly1305 = __commonJS((exports, module) => {
|
|
268965
268970
|
var __dirname = "/home/runner/work/publisher/publisher/node_modules/ssh2/lib/protocol/crypto", __filename = "/home/runner/work/publisher/publisher/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
|
|
@@ -269446,7 +269451,7 @@ var require_crypto = __commonJS((exports, module) => {
|
|
|
269446
269451
|
var ChaChaPolyDecipher;
|
|
269447
269452
|
var GenericDecipher;
|
|
269448
269453
|
try {
|
|
269449
|
-
binding = (
|
|
269454
|
+
binding = require_sshcrypto();
|
|
269450
269455
|
({
|
|
269451
269456
|
AESGCMCipher,
|
|
269452
269457
|
ChaChaPolyCipher,
|
|
@@ -283780,7 +283785,7 @@ function validateMotherDuckShape(connection) {
|
|
|
283780
283785
|
throw new Error("MotherDuck access token is required.");
|
|
283781
283786
|
}
|
|
283782
283787
|
}
|
|
283783
|
-
function validateDuckLakeShape(connection) {
|
|
283788
|
+
function validateDuckLakeShape(connection, origin2) {
|
|
283784
283789
|
if (!connection.ducklakeConnection) {
|
|
283785
283790
|
throw new Error("DuckLake connection configuration is missing.");
|
|
283786
283791
|
}
|
|
@@ -283789,7 +283794,7 @@ function validateDuckLakeShape(connection) {
|
|
|
283789
283794
|
}
|
|
283790
283795
|
const storage = connection.ducklakeConnection.storage;
|
|
283791
283796
|
if (storage?.s3Connection) {
|
|
283792
|
-
validateS3ProviderShape(storage.s3Connection, connection.name);
|
|
283797
|
+
validateS3ProviderShape(storage.s3Connection, connection.name, origin2);
|
|
283793
283798
|
}
|
|
283794
283799
|
if (connection.ducklakeConnection.catalog.metadataSchema !== undefined) {
|
|
283795
283800
|
const schema = connection.ducklakeConnection.catalog.metadataSchema;
|
|
@@ -283866,7 +283871,7 @@ function validatePublisherShape(connection) {
|
|
|
283866
283871
|
throw new Error(`Invalid publisher connection '${connection.name}': connectionUri must use http or https (got '${parsedUri.protocol}'). ` + `Fix: set connectionUri to an absolute https URL like "https://…/connections/${connection.name}".`);
|
|
283867
283872
|
}
|
|
283868
283873
|
}
|
|
283869
|
-
function validateTypeShape(connection) {
|
|
283874
|
+
function validateTypeShape(connection, origin2) {
|
|
283870
283875
|
switch (connection.type) {
|
|
283871
283876
|
case "sqlserver":
|
|
283872
283877
|
return validateSqlServerShape(connection);
|
|
@@ -283877,7 +283882,7 @@ function validateTypeShape(connection) {
|
|
|
283877
283882
|
case "motherduck":
|
|
283878
283883
|
return validateMotherDuckShape(connection);
|
|
283879
283884
|
case "ducklake":
|
|
283880
|
-
return validateDuckLakeShape(connection);
|
|
283885
|
+
return validateDuckLakeShape(connection, origin2);
|
|
283881
283886
|
case "trino":
|
|
283882
283887
|
return validateTrinoShape(connection);
|
|
283883
283888
|
case "databricks":
|
|
@@ -283888,7 +283893,7 @@ function validateTypeShape(connection) {
|
|
|
283888
283893
|
return validatePublisherShape(connection);
|
|
283889
283894
|
}
|
|
283890
283895
|
}
|
|
283891
|
-
function validateConnectionShape(connection) {
|
|
283896
|
+
function validateConnectionShape(connection, origin2 = "connection") {
|
|
283892
283897
|
if (connection.proxy) {
|
|
283893
283898
|
validateProxyShape(connection, connection.proxy);
|
|
283894
283899
|
}
|
|
@@ -283901,7 +283906,7 @@ function validateConnectionShape(connection) {
|
|
|
283901
283906
|
if (connection.postgresConnection) {
|
|
283902
283907
|
postgresStatementTimeoutMs(connection.name ?? "", connection.postgresConnection);
|
|
283903
283908
|
}
|
|
283904
|
-
validateTypeShape(connection);
|
|
283909
|
+
validateTypeShape(connection, origin2);
|
|
283905
283910
|
}
|
|
283906
283911
|
function storageDestinationRoot(environmentPath) {
|
|
283907
283912
|
return path4.join(environmentPath, STORAGE_DESTINATIONS_DIR);
|
|
@@ -283950,7 +283955,7 @@ function validateStorageDestinations(destinations = []) {
|
|
|
283950
283955
|
continue;
|
|
283951
283956
|
}
|
|
283952
283957
|
try {
|
|
283953
|
-
validateConnectionShape(destination);
|
|
283958
|
+
validateConnectionShape(destination, "storage-destination");
|
|
283954
283959
|
const storage = destination.ducklakeConnection?.storage;
|
|
283955
283960
|
if (storage?.s3Connection) {
|
|
283956
283961
|
resolveCloudStorageCredentials({
|
|
@@ -284168,7 +284173,7 @@ function buildCoreEntry(connection, environmentPath) {
|
|
|
284168
284173
|
throw new Error(`Unsupported connection type: ${connection.type}`);
|
|
284169
284174
|
}
|
|
284170
284175
|
}
|
|
284171
|
-
function assembleEnvironmentConnections(connections = [], environmentPath = "") {
|
|
284176
|
+
function assembleEnvironmentConnections(connections = [], environmentPath = "", origin2 = "connection") {
|
|
284172
284177
|
const pojo = { connections: {} };
|
|
284173
284178
|
const metadata = new Map;
|
|
284174
284179
|
const apiConnections = [];
|
|
@@ -284185,7 +284190,7 @@ function assembleEnvironmentConnections(connections = [], environmentPath = "")
|
|
|
284185
284190
|
}
|
|
284186
284191
|
processedConnections.add(connection.name);
|
|
284187
284192
|
validateDuckdbApiSurface(connection);
|
|
284188
|
-
validateConnectionShape(connection);
|
|
284193
|
+
validateConnectionShape(connection, origin2);
|
|
284189
284194
|
warnOnConnectionQueryMetadata(connection);
|
|
284190
284195
|
const apiConnection = cloneApiConnection(connection);
|
|
284191
284196
|
apiConnection.attributes = getStaticConnectionAttributes(connection.type);
|
|
@@ -295166,17 +295171,19 @@ async function attachDuckLakeWithMode(connection, dbName, ducklakeConfig, option
|
|
|
295166
295171
|
const hasS3 = !!ducklakeConfig.storage?.s3Connection;
|
|
295167
295172
|
const hasGCS = !!ducklakeConfig.storage?.gcsConnection;
|
|
295168
295173
|
if (hasS3) {
|
|
295169
|
-
await
|
|
295170
|
-
|
|
295171
|
-
|
|
295172
|
-
|
|
295173
|
-
|
|
295174
|
-
|
|
295175
|
-
|
|
295176
|
-
|
|
295177
|
-
|
|
295178
|
-
|
|
295179
|
-
|
|
295174
|
+
await connection.runSQL("SET GLOBAL enable_global_s3_configuration=false");
|
|
295175
|
+
}
|
|
295176
|
+
const storage = hasS3 ? {
|
|
295177
|
+
name: `${dbName}_storage`,
|
|
295178
|
+
type: "s3",
|
|
295179
|
+
s3Connection: ducklakeConfig.storage.s3Connection
|
|
295180
|
+
} : hasGCS ? {
|
|
295181
|
+
name: `${dbName}_storage`,
|
|
295182
|
+
type: "gcs",
|
|
295183
|
+
gcsConnection: ducklakeConfig.storage.gcsConnection
|
|
295184
|
+
} : undefined;
|
|
295185
|
+
if (storage) {
|
|
295186
|
+
resolveCloudStorageCredentials(storage, options.origin ?? "connection");
|
|
295180
295187
|
}
|
|
295181
295188
|
const pg = ducklakeConfig.catalog.postgresConnection;
|
|
295182
295189
|
const pgConnString = buildPgConnectionString(pg, {
|
|
@@ -295189,8 +295196,8 @@ async function attachDuckLakeWithMode(connection, dbName, ducklakeConfig, option
|
|
|
295189
295196
|
logger.debug(`Final escaped connection string: ${redactPgSecrets(escapedPgConnString)}`);
|
|
295190
295197
|
const dataPath = ducklakeConfig.storage?.bucketUrl;
|
|
295191
295198
|
const metadataSchema = ducklakeConfig.catalog.metadataSchema;
|
|
295192
|
-
const
|
|
295193
|
-
if (
|
|
295199
|
+
const preflight = await preflightDuckLakeCatalogFormat(connection, dbName, pgConnString, metadataSchema);
|
|
295200
|
+
if (preflight === "absent") {
|
|
295194
295201
|
if (options.skipIfAbsent) {
|
|
295195
295202
|
return false;
|
|
295196
295203
|
}
|
|
@@ -295215,14 +295222,44 @@ async function attachDuckLakeWithMode(connection, dbName, ducklakeConfig, option
|
|
|
295215
295222
|
throw error;
|
|
295216
295223
|
}
|
|
295217
295224
|
}
|
|
295225
|
+
if (storage) {
|
|
295226
|
+
try {
|
|
295227
|
+
const scope = await attachedDuckLakeScope(connection, dbName, {
|
|
295228
|
+
configuredDataPath: dataPath,
|
|
295229
|
+
metadataSchema,
|
|
295230
|
+
readOnly: options.readOnly,
|
|
295231
|
+
managed: options.managed === true && options.origin !== "storage-destination"
|
|
295232
|
+
});
|
|
295233
|
+
if (!scope) {
|
|
295234
|
+
throw new Error(`No storage secret could be scoped for DuckLake catalog '${dbName}': ` + `the config states no data path, and the catalog records no data ` + `path (or, for a managed view, no path for its main schema) to ` + `scope it to. The catalog was not attached.`);
|
|
295235
|
+
}
|
|
295236
|
+
await attachCloudStorage(connection, storage, options.origin, scope);
|
|
295237
|
+
} catch (error) {
|
|
295238
|
+
await connection.runSQL(`DETACH ${quoteIdentifier(dbName, "duckdb")};`).catch(() => {});
|
|
295239
|
+
throw error;
|
|
295240
|
+
}
|
|
295241
|
+
}
|
|
295218
295242
|
return true;
|
|
295219
295243
|
}
|
|
295220
|
-
async function
|
|
295221
|
-
const
|
|
295244
|
+
async function attachedDuckLakeScope(connection, dbName, input) {
|
|
295245
|
+
const recordedDataPath = input.configuredDataPath ? undefined : (await recordedCatalogSettings(connection, dbName, input.metadataSchema)).data_path;
|
|
295246
|
+
const mainSchemaPath = input.managed && input.readOnly ? await recordedSchemaPath(connection, dbName, input.metadataSchema, "main") : undefined;
|
|
295247
|
+
return storageSecretScope({
|
|
295248
|
+
configuredDataPath: input.configuredDataPath,
|
|
295249
|
+
recordedDataPath,
|
|
295250
|
+
mainSchemaPath,
|
|
295251
|
+
readOnly: input.readOnly,
|
|
295252
|
+
managed: input.managed
|
|
295253
|
+
});
|
|
295254
|
+
}
|
|
295255
|
+
function metadataCatalogRef(alias, metadataSchema) {
|
|
295256
|
+
return [
|
|
295222
295257
|
`__ducklake_metadata_${alias}`,
|
|
295223
295258
|
...metadataSchema ? [metadataSchema] : []
|
|
295224
295259
|
].map((part) => quoteIdentifier(part, "duckdb")).join(".");
|
|
295225
|
-
|
|
295260
|
+
}
|
|
295261
|
+
async function recordedCatalogSettings(connection, alias, metadataSchema) {
|
|
295262
|
+
const rows = runSQLRows(await connection.runSQL(`SELECT key, value FROM ${metadataCatalogRef(alias, metadataSchema)}.ducklake_metadata WHERE scope IS NULL`));
|
|
295226
295263
|
const settings = {};
|
|
295227
295264
|
for (const row of rows) {
|
|
295228
295265
|
if (typeof row.key === "string" && row.value != null) {
|
|
@@ -295231,6 +295268,43 @@ async function recordedCatalogSettings(connection, alias, metadataSchema) {
|
|
|
295231
295268
|
}
|
|
295232
295269
|
return settings;
|
|
295233
295270
|
}
|
|
295271
|
+
async function recordedSchemaPath(connection, alias, metadataSchema, schemaName) {
|
|
295272
|
+
const row = runSQLRows(await connection.runSQL(`SELECT path, path_is_relative FROM ${metadataCatalogRef(alias, metadataSchema)}.ducklake_schema ` + `WHERE schema_name = '${escapeSQL(schemaName)}' AND end_snapshot IS NULL LIMIT 1`))[0];
|
|
295273
|
+
if (!row || typeof row.path !== "string")
|
|
295274
|
+
return;
|
|
295275
|
+
return { path: row.path, relative: row.path_is_relative !== false };
|
|
295276
|
+
}
|
|
295277
|
+
function stripTrailingSlashes(url3) {
|
|
295278
|
+
let end = url3.length;
|
|
295279
|
+
while (end > 0 && url3[end - 1] === "/")
|
|
295280
|
+
end--;
|
|
295281
|
+
return url3.slice(0, end);
|
|
295282
|
+
}
|
|
295283
|
+
function oneTrailingSlash(url3) {
|
|
295284
|
+
return `${stripTrailingSlashes(url3)}/`;
|
|
295285
|
+
}
|
|
295286
|
+
function isBucketlessUrl(url3) {
|
|
295287
|
+
const at = url3.indexOf("://");
|
|
295288
|
+
return at >= 0 && stripTrailingSlashes(url3.slice(at + 3)) === "";
|
|
295289
|
+
}
|
|
295290
|
+
function storageSecretScope(input) {
|
|
295291
|
+
const root = input.configuredDataPath || input.recordedDataPath;
|
|
295292
|
+
if (!root || isBucketlessUrl(root))
|
|
295293
|
+
return;
|
|
295294
|
+
if (input.managed && input.readOnly) {
|
|
295295
|
+
const main = input.mainSchemaPath;
|
|
295296
|
+
if (!main)
|
|
295297
|
+
return;
|
|
295298
|
+
if (!main.relative) {
|
|
295299
|
+
return isBucketlessUrl(main.path) ? undefined : oneTrailingSlash(main.path);
|
|
295300
|
+
}
|
|
295301
|
+
let start = 0;
|
|
295302
|
+
while (start < main.path.length && main.path[start] === "/")
|
|
295303
|
+
start++;
|
|
295304
|
+
return oneTrailingSlash(`${oneTrailingSlash(root)}${main.path.slice(start)}`);
|
|
295305
|
+
}
|
|
295306
|
+
return oneTrailingSlash(root);
|
|
295307
|
+
}
|
|
295234
295308
|
function dataPathClauses(dataPath, readOnly) {
|
|
295235
295309
|
if (dataPath) {
|
|
295236
295310
|
return `DATA_PATH '${escapeSQL(dataPath)}', OVERRIDE_DATA_PATH true`;
|
|
@@ -295250,13 +295324,16 @@ function firstAttachClauses(options) {
|
|
|
295250
295324
|
async function attachDuckLakeForCreate(connection, dbName, ducklakeConfig, settings) {
|
|
295251
295325
|
await attachDuckLakeWithMode(connection, dbName, ducklakeConfig, {
|
|
295252
295326
|
readOnly: false,
|
|
295327
|
+
origin: "storage-destination",
|
|
295253
295328
|
encrypted: settings.encrypted,
|
|
295254
295329
|
dataInliningRowLimit: settings.dataInliningRowLimit
|
|
295255
295330
|
});
|
|
295256
295331
|
}
|
|
295257
|
-
async function attachDuckLake(connection, dbName, ducklakeConfig) {
|
|
295332
|
+
async function attachDuckLake(connection, dbName, ducklakeConfig, options = {}) {
|
|
295258
295333
|
await attachDuckLakeWithMode(connection, dbName, ducklakeConfig, {
|
|
295259
|
-
readOnly: ducklakeConfig.readOnly !== false
|
|
295334
|
+
readOnly: ducklakeConfig.readOnly !== false,
|
|
295335
|
+
origin: options.origin,
|
|
295336
|
+
managed: options.managed
|
|
295260
295337
|
});
|
|
295261
295338
|
}
|
|
295262
295339
|
function managedSearchPathSql(dbName) {
|
|
@@ -295267,17 +295344,21 @@ async function setManagedSearchPath(connection, dbName) {
|
|
|
295267
295344
|
await connection.runSQL(managedSearchPathSql(dbName));
|
|
295268
295345
|
}
|
|
295269
295346
|
async function attachDuckLakeReadOnly(connection, dbName, ducklakeConfig) {
|
|
295270
|
-
await attachDuckLake(connection, dbName, ducklakeConfig
|
|
295347
|
+
await attachDuckLake(connection, dbName, ducklakeConfig, {
|
|
295348
|
+
origin: "storage-destination"
|
|
295349
|
+
});
|
|
295271
295350
|
}
|
|
295272
295351
|
async function attachDuckLakeReadOnlyIfPresent(connection, dbName, ducklakeConfig) {
|
|
295273
295352
|
return attachDuckLakeWithMode(connection, dbName, ducklakeConfig, {
|
|
295274
295353
|
readOnly: true,
|
|
295275
|
-
skipIfAbsent: true
|
|
295354
|
+
skipIfAbsent: true,
|
|
295355
|
+
origin: "storage-destination"
|
|
295276
295356
|
});
|
|
295277
295357
|
}
|
|
295278
295358
|
async function attachDuckLakeReadWrite(connection, dbName, ducklakeConfig) {
|
|
295279
295359
|
await attachDuckLakeWithMode(connection, dbName, ducklakeConfig, {
|
|
295280
|
-
readOnly: false
|
|
295360
|
+
readOnly: false,
|
|
295361
|
+
origin: "storage-destination"
|
|
295281
295362
|
});
|
|
295282
295363
|
}
|
|
295283
295364
|
async function federateSourceForPassthrough(connection, sourceType, config, deps = {}) {
|
|
@@ -295481,13 +295562,15 @@ function buildCloudStorageSecretSQL(secretName, credentials) {
|
|
|
295481
295562
|
const isGCS = credentials.type === "gcs";
|
|
295482
295563
|
const escapedKeyId = escapeSQL(credentials.accessKeyId);
|
|
295483
295564
|
const escapedSecret = escapeSQL(credentials.secretAccessKey);
|
|
295565
|
+
const scopeClause = credentials.scope ? `SCOPE '${escapeSQL(credentials.scope)}'` : "";
|
|
295484
295566
|
let createSecretCommand;
|
|
295485
295567
|
if (isGCS) {
|
|
295486
295568
|
createSecretCommand = `
|
|
295487
295569
|
CREATE OR REPLACE SECRET ${secretName} (
|
|
295488
295570
|
TYPE gcs,
|
|
295489
295571
|
KEY_ID '${escapedKeyId}',
|
|
295490
|
-
SECRET '${escapedSecret}'
|
|
295572
|
+
SECRET '${escapedSecret}'${scopeClause ? `,
|
|
295573
|
+
${scopeClause}` : ""}
|
|
295491
295574
|
);
|
|
295492
295575
|
`;
|
|
295493
295576
|
} else {
|
|
@@ -295523,6 +295606,9 @@ function buildCloudStorageSecretSQL(secretName, credentials) {
|
|
|
295523
295606
|
if (credentials.provider !== "credential_chain" && credentials.sessionToken) {
|
|
295524
295607
|
clauses.push(`SESSION_TOKEN '${escapeSQL(credentials.sessionToken)}'`);
|
|
295525
295608
|
}
|
|
295609
|
+
if (scopeClause) {
|
|
295610
|
+
clauses.push(scopeClause);
|
|
295611
|
+
}
|
|
295526
295612
|
createSecretCommand = `
|
|
295527
295613
|
CREATE OR REPLACE SECRET ${secretName} (
|
|
295528
295614
|
${clauses.join(`,
|
|
@@ -295532,9 +295618,12 @@ function buildCloudStorageSecretSQL(secretName, credentials) {
|
|
|
295532
295618
|
}
|
|
295533
295619
|
return createSecretCommand;
|
|
295534
295620
|
}
|
|
295535
|
-
async function attachCloudStorage(connection, attachedDb) {
|
|
295621
|
+
async function attachCloudStorage(connection, attachedDb, origin2 = "connection", scope) {
|
|
295536
295622
|
const storageType = attachedDb.type?.toUpperCase() || "";
|
|
295537
|
-
const credentials =
|
|
295623
|
+
const credentials = {
|
|
295624
|
+
...resolveCloudStorageCredentials(attachedDb, origin2),
|
|
295625
|
+
scope
|
|
295626
|
+
};
|
|
295538
295627
|
await installAndLoadExtension(connection, "httpfs");
|
|
295539
295628
|
if (credentials.provider === "credential_chain") {
|
|
295540
295629
|
await installAndLoadExtension(connection, "aws");
|
|
@@ -295826,8 +295915,8 @@ function applyConnectionFingerprint(connection, metadata) {
|
|
|
295826
295915
|
function isDuckDBConnection(connection) {
|
|
295827
295916
|
return connection instanceof DuckDBConnection;
|
|
295828
295917
|
}
|
|
295829
|
-
function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", isUpdateConnectionRequest = false) {
|
|
295830
|
-
const assembled = assembleEnvironmentConnections(connections, environmentPath);
|
|
295918
|
+
function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", isUpdateConnectionRequest = false, { origin: origin2 = "connection" } = {}) {
|
|
295919
|
+
const assembled = assembleEnvironmentConnections(connections, environmentPath, origin2);
|
|
295831
295920
|
const duckLakeCache = new Map;
|
|
295832
295921
|
const snowflakeJwtCache = new Map;
|
|
295833
295922
|
const azureDuckDBCache = new Map;
|
|
@@ -295866,7 +295955,10 @@ function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", is
|
|
|
295866
295955
|
}
|
|
295867
295956
|
const connection2 = await connectionPromise;
|
|
295868
295957
|
if (isUpdateConnectionRequest || !await isDatabaseAttached(connection2, name)) {
|
|
295869
|
-
await attachDuckLake(connection2, name, metadata.apiConnection.ducklakeConnection
|
|
295958
|
+
await attachDuckLake(connection2, name, metadata.apiConnection.ducklakeConnection, {
|
|
295959
|
+
origin: origin2,
|
|
295960
|
+
managed: metadata.apiConnection.managed === true
|
|
295961
|
+
});
|
|
295870
295962
|
if (metadata.apiConnection.managed === true) {
|
|
295871
295963
|
await setManagedSearchPath(connection2, name);
|
|
295872
295964
|
}
|
|
@@ -370400,10 +370492,10 @@ class Environment {
|
|
|
370400
370492
|
if (this.destinations.length > 0) {
|
|
370401
370493
|
fs17.mkdirSync(destinationRoot, { recursive: true });
|
|
370402
370494
|
}
|
|
370403
|
-
this.destinationMalloyConfig = buildEnvironmentMalloyConfig(this.destinations, destinationRoot);
|
|
370495
|
+
this.destinationMalloyConfig = buildEnvironmentMalloyConfig(this.destinations, destinationRoot, false, { origin: "storage-destination" });
|
|
370404
370496
|
} catch (error) {
|
|
370405
370497
|
logger.error(`Failed to assemble storage destinations for environment ${this.environmentName}; serving without them`, { error });
|
|
370406
|
-
this.destinationMalloyConfig = buildEnvironmentMalloyConfig([], storageDestinationRoot(this.environmentPath));
|
|
370498
|
+
this.destinationMalloyConfig = buildEnvironmentMalloyConfig([], storageDestinationRoot(this.environmentPath), false, { origin: "storage-destination" });
|
|
370407
370499
|
}
|
|
370408
370500
|
if (previous && previous !== this.destinationMalloyConfig) {
|
|
370409
370501
|
this.retireConnectionGeneration(`environment ${this.environmentName} destinations`, () => previous.releaseConnections());
|
|
@@ -377082,7 +377174,7 @@ function readerSql(uri, format, options = {}) {
|
|
|
377082
377174
|
return `read_parquet(${path25})`;
|
|
377083
377175
|
}
|
|
377084
377176
|
function assertUnderDataPath(uri, dataPath) {
|
|
377085
|
-
const root = dataPath
|
|
377177
|
+
const root = stripTrailingSlashes(dataPath);
|
|
377086
377178
|
const outside = () => new BadRequestError(`The object must sit under the catalog's data path (${root}/).`);
|
|
377087
377179
|
if (!root || !uri.startsWith(`${root}/`))
|
|
377088
377180
|
throw outside();
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|