@malloy-publisher/server 0.11.0 → 0.11.2
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 +58 -0
- package/dist/instrumentation.mjs +1 -1
- package/dist/package_load_worker.mjs +6 -1
- package/dist/server.mjs +307 -41
- package/package.json +1 -1
package/dist/app/api-doc.yaml
CHANGED
|
@@ -5365,6 +5365,37 @@ components:
|
|
|
5365
5365
|
Fetch one with `GET .../agents/{agentName}`.
|
|
5366
5366
|
items:
|
|
5367
5367
|
$ref: "#/components/schemas/AgentSummary"
|
|
5368
|
+
secureGivens:
|
|
5369
|
+
type: array
|
|
5370
|
+
readOnly: true
|
|
5371
|
+
description: >-
|
|
5372
|
+
Server-computed, read-only: every `#(secure)` given the package's
|
|
5373
|
+
compiled models surface, so a host that sets those values learns
|
|
5374
|
+
which ones to set from the load response without compiling the
|
|
5375
|
+
package itself.
|
|
5376
|
+
|
|
5377
|
+
|
|
5378
|
+
Collected from every `.malloy` model and `.malloynb` notebook in
|
|
5379
|
+
the package, files outside `explores` included. A model's givens
|
|
5380
|
+
are the ones its `CompiledModel.givens` reports, so a given
|
|
5381
|
+
declared in one file and imported by another is listed under both;
|
|
5382
|
+
a notebook's are those of the model its cells build up to. One
|
|
5383
|
+
entry per distinct `name` and `type`, sorted by `name` then `type`;
|
|
5384
|
+
a name declared with two types is two entries. It always describes
|
|
5385
|
+
the models the package is serving now, so a reload that changes
|
|
5386
|
+
them changes it.
|
|
5387
|
+
|
|
5388
|
+
|
|
5389
|
+
Present, possibly empty, on a loaded package whose every model and
|
|
5390
|
+
notebook compiled, so `[]` means the package declares no secure
|
|
5391
|
+
given. Absent when the list cannot be known to be complete: when
|
|
5392
|
+
any model or notebook in the package failed to compile (a reload
|
|
5393
|
+
keeps serving the files that did), or when the server does not
|
|
5394
|
+
report it, as on a listing entry for a package that is not loaded.
|
|
5395
|
+
Treat absent as unknown, never as none. It cannot be set: a PATCH
|
|
5396
|
+
body carrying it is ignored.
|
|
5397
|
+
items:
|
|
5398
|
+
$ref: "#/components/schemas/SecureGivenSummary"
|
|
5368
5399
|
|
|
5369
5400
|
AgentSchedule:
|
|
5370
5401
|
type: object
|
|
@@ -6571,6 +6602,33 @@ components:
|
|
|
6571
6602
|
Malloy data type of the dimension (e.g. string, number, boolean,
|
|
6572
6603
|
date, timestamp)
|
|
6573
6604
|
|
|
6605
|
+
SecureGivenSummary:
|
|
6606
|
+
type: object
|
|
6607
|
+
readOnly: true
|
|
6608
|
+
description: >-
|
|
6609
|
+
One `#(secure)` given in a package's `secureGivens`: a given whose
|
|
6610
|
+
value the host sets, and the model files that surface it.
|
|
6611
|
+
required:
|
|
6612
|
+
- name
|
|
6613
|
+
- type
|
|
6614
|
+
- modelPaths
|
|
6615
|
+
properties:
|
|
6616
|
+
name:
|
|
6617
|
+
type: string
|
|
6618
|
+
description: Name as declared in the model.
|
|
6619
|
+
type:
|
|
6620
|
+
type: string
|
|
6621
|
+
description: >-
|
|
6622
|
+
The given's type, rendered exactly as `Given.type` renders it
|
|
6623
|
+
(e.g. `string`, `number`, `string[]`, `filter<string>`).
|
|
6624
|
+
modelPaths:
|
|
6625
|
+
type: array
|
|
6626
|
+
description: >-
|
|
6627
|
+
Package-relative paths of the `.malloy` models and `.malloynb`
|
|
6628
|
+
notebooks whose compiled givens include this given, the declaring
|
|
6629
|
+
file and every file that imports it alike. Sorted, no duplicates.
|
|
6630
|
+
items:
|
|
6631
|
+
type: string
|
|
6574
6632
|
Given:
|
|
6575
6633
|
type: object
|
|
6576
6634
|
description: |
|
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.11.
|
|
164834
|
+
var version = "0.11.2";
|
|
164835
164835
|
var init_package = () => {};
|
|
164836
164836
|
|
|
164837
164837
|
// src/version.ts
|
|
@@ -14201,6 +14201,11 @@ function withPlaceholderDefaults(givens) {
|
|
|
14201
14201
|
}
|
|
14202
14202
|
var init_model_info = () => {};
|
|
14203
14203
|
|
|
14204
|
+
// src/compare_text.ts
|
|
14205
|
+
function compareText(a, b) {
|
|
14206
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
14207
|
+
}
|
|
14208
|
+
|
|
14204
14209
|
// src/service/package_revision.ts
|
|
14205
14210
|
import { createHash, randomUUID } from "crypto";
|
|
14206
14211
|
import fs from "fs";
|
|
@@ -14223,7 +14228,7 @@ function computeSourceContentSha(packagePath, contentPaths, extra) {
|
|
|
14223
14228
|
return hash.digest("hex");
|
|
14224
14229
|
}
|
|
14225
14230
|
function canonicalJson(value) {
|
|
14226
|
-
return JSON.stringify(value, (_key, v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a
|
|
14231
|
+
return JSON.stringify(value, (_key, v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => compareText(a, b))) : v);
|
|
14227
14232
|
}
|
|
14228
14233
|
function boundedManifestValue(value) {
|
|
14229
14234
|
try {
|
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.11.
|
|
164835
|
+
var version = "0.11.2";
|
|
164836
164836
|
var init_package = () => {};
|
|
164837
164837
|
|
|
164838
164838
|
// src/version.ts
|
|
@@ -283159,7 +283159,21 @@ function openSshProxy(ssh, target) {
|
|
|
283159
283159
|
let localPort = 0;
|
|
283160
283160
|
let server;
|
|
283161
283161
|
let settled = false;
|
|
283162
|
+
let opened = false;
|
|
283163
|
+
let dead = false;
|
|
283164
|
+
let closing = false;
|
|
283165
|
+
let lastError;
|
|
283166
|
+
let deathCause;
|
|
283167
|
+
const closeListeners = [];
|
|
283168
|
+
let closePromise;
|
|
283162
283169
|
const sockets = new Set;
|
|
283170
|
+
function notifyClose(listener) {
|
|
283171
|
+
try {
|
|
283172
|
+
listener(deathCause);
|
|
283173
|
+
} catch (err) {
|
|
283174
|
+
logger.warn("SSH tunnel onClose listener threw", { error: err });
|
|
283175
|
+
}
|
|
283176
|
+
}
|
|
283163
283177
|
function fail(err) {
|
|
283164
283178
|
if (settled)
|
|
283165
283179
|
return;
|
|
@@ -283195,34 +283209,64 @@ function openSshProxy(ssh, target) {
|
|
|
283195
283209
|
return false;
|
|
283196
283210
|
}
|
|
283197
283211
|
};
|
|
283198
|
-
client.on("error", (err) =>
|
|
283212
|
+
client.on("error", (err) => {
|
|
283213
|
+
lastError = err;
|
|
283214
|
+
fail(err);
|
|
283215
|
+
});
|
|
283216
|
+
function onSessionGone(err) {
|
|
283217
|
+
if (err)
|
|
283218
|
+
lastError ??= err;
|
|
283219
|
+
if (!opened) {
|
|
283220
|
+
fail(lastError ?? new Error(`SSH connection to ${ssh.host} closed before the tunnel was ready`));
|
|
283221
|
+
return;
|
|
283222
|
+
}
|
|
283223
|
+
if (closing || dead)
|
|
283224
|
+
return;
|
|
283225
|
+
dead = true;
|
|
283226
|
+
deathCause = lastError;
|
|
283227
|
+
logger.warn(`SSH tunnel via bastion ${ssh.host} to ${target.host}:${target.port} closed` + (lastError ? `: ${lastError.message}` : "."));
|
|
283228
|
+
for (const listener of closeListeners.splice(0))
|
|
283229
|
+
notifyClose(listener);
|
|
283230
|
+
}
|
|
283231
|
+
client.on("close", () => onSessionGone());
|
|
283232
|
+
client.on("end", () => onSessionGone());
|
|
283199
283233
|
client.on("ready", () => {
|
|
283200
283234
|
server = net.createServer((socket) => {
|
|
283235
|
+
if (dead) {
|
|
283236
|
+
socket.destroy();
|
|
283237
|
+
return;
|
|
283238
|
+
}
|
|
283201
283239
|
sockets.add(socket);
|
|
283202
283240
|
socket.on("close", () => sockets.delete(socket));
|
|
283241
|
+
socket.on("error", () => {});
|
|
283203
283242
|
const earlyData = [];
|
|
283204
283243
|
socket.on("data", (chunk) => earlyData.push(chunk));
|
|
283205
|
-
|
|
283206
|
-
|
|
283207
|
-
|
|
283208
|
-
|
|
283209
|
-
|
|
283210
|
-
|
|
283211
|
-
|
|
283212
|
-
|
|
283213
|
-
|
|
283214
|
-
|
|
283215
|
-
|
|
283216
|
-
|
|
283217
|
-
|
|
283218
|
-
|
|
283219
|
-
|
|
283220
|
-
|
|
283221
|
-
|
|
283222
|
-
|
|
283223
|
-
|
|
283224
|
-
|
|
283225
|
-
|
|
283244
|
+
try {
|
|
283245
|
+
client.forwardOut("127.0.0.1", localPort, target.host, target.port, (err, channel) => {
|
|
283246
|
+
if (err) {
|
|
283247
|
+
socket.destroy(err);
|
|
283248
|
+
return;
|
|
283249
|
+
}
|
|
283250
|
+
if (socket.destroyed) {
|
|
283251
|
+
channel.destroy();
|
|
283252
|
+
return;
|
|
283253
|
+
}
|
|
283254
|
+
for (const chunk of earlyData) {
|
|
283255
|
+
channel.write(chunk);
|
|
283256
|
+
}
|
|
283257
|
+
earlyData.length = 0;
|
|
283258
|
+
socket.removeAllListeners("data");
|
|
283259
|
+
socket.pipe(channel);
|
|
283260
|
+
channel.pipe(socket);
|
|
283261
|
+
socket.on("error", () => channel.destroy());
|
|
283262
|
+
channel.on("error", () => socket.destroy());
|
|
283263
|
+
socket.on("close", () => channel.destroy());
|
|
283264
|
+
channel.on("close", () => socket.destroy());
|
|
283265
|
+
});
|
|
283266
|
+
} catch (err) {
|
|
283267
|
+
socket.destroy(err);
|
|
283268
|
+
onSessionGone(err);
|
|
283269
|
+
}
|
|
283226
283270
|
});
|
|
283227
283271
|
server.listen(0, "127.0.0.1", () => {
|
|
283228
283272
|
const addr = server.address();
|
|
@@ -283231,14 +283275,18 @@ function openSshProxy(ssh, target) {
|
|
|
283231
283275
|
return;
|
|
283232
283276
|
}
|
|
283233
283277
|
localPort = addr.port;
|
|
283234
|
-
if (settled)
|
|
283278
|
+
if (settled) {
|
|
283279
|
+
server.close();
|
|
283235
283280
|
return;
|
|
283281
|
+
}
|
|
283236
283282
|
settled = true;
|
|
283283
|
+
opened = true;
|
|
283237
283284
|
resolve2({
|
|
283238
283285
|
host: "127.0.0.1",
|
|
283239
283286
|
port: localPort,
|
|
283240
283287
|
close() {
|
|
283241
|
-
|
|
283288
|
+
closing = true;
|
|
283289
|
+
closePromise ??= new Promise((res) => {
|
|
283242
283290
|
for (const s2 of sockets)
|
|
283243
283291
|
s2.destroy();
|
|
283244
283292
|
server.close(() => {
|
|
@@ -283246,6 +283294,19 @@ function openSshProxy(ssh, target) {
|
|
|
283246
283294
|
res();
|
|
283247
283295
|
});
|
|
283248
283296
|
});
|
|
283297
|
+
return closePromise;
|
|
283298
|
+
},
|
|
283299
|
+
onClose(listener) {
|
|
283300
|
+
if (closing)
|
|
283301
|
+
return;
|
|
283302
|
+
if (dead) {
|
|
283303
|
+
process.nextTick(() => {
|
|
283304
|
+
if (!closing)
|
|
283305
|
+
notifyClose(listener);
|
|
283306
|
+
});
|
|
283307
|
+
return;
|
|
283308
|
+
}
|
|
283309
|
+
closeListeners.push(listener);
|
|
283249
283310
|
}
|
|
283250
283311
|
});
|
|
283251
283312
|
});
|
|
@@ -295931,13 +295992,11 @@ function buildProxiedPostgresConnection(metadata, endpoint) {
|
|
|
295931
295992
|
const { query, ssl } = resolveProxiedTls(name, pg.host, pg.sslmode);
|
|
295932
295993
|
const connectionString = `postgresql://${auth}${endpoint.host}:${endpoint.port}${db}${query}`;
|
|
295933
295994
|
const setupSQL = statementTimeoutSetupSQL(name, pg);
|
|
295934
|
-
return new
|
|
295995
|
+
return new EnvironmentPooledPostgresConnection({
|
|
295935
295996
|
name,
|
|
295936
295997
|
connectionString,
|
|
295937
295998
|
...ssl ? { ssl } : {},
|
|
295938
|
-
...setupSQL ? { setupSQL } : {}
|
|
295939
|
-
poolMin: 1,
|
|
295940
|
-
poolMax: 20
|
|
295999
|
+
...setupSQL ? { setupSQL } : {}
|
|
295941
296000
|
});
|
|
295942
296001
|
}
|
|
295943
296002
|
function buildEnvironmentPostgresConnection(metadata) {
|
|
@@ -295983,7 +296042,10 @@ function applyConnectionFingerprint(connection, metadata) {
|
|
|
295983
296042
|
function isDuckDBConnection(connection) {
|
|
295984
296043
|
return connection instanceof DuckDBConnection;
|
|
295985
296044
|
}
|
|
295986
|
-
function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", isUpdateConnectionRequest = false, {
|
|
296045
|
+
function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", isUpdateConnectionRequest = false, {
|
|
296046
|
+
origin: origin2 = "connection",
|
|
296047
|
+
openProxy: openTunnel = openProxy
|
|
296048
|
+
} = {}) {
|
|
295987
296049
|
const assembled = assembleEnvironmentConnections(connections, environmentPath, origin2);
|
|
295988
296050
|
const duckLakeCache = new Map;
|
|
295989
296051
|
const snowflakeJwtCache = new Map;
|
|
@@ -295992,6 +296054,16 @@ function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", is
|
|
|
295992
296054
|
const postgresConnectionCache = new Map;
|
|
295993
296055
|
const proxyEndpoints = new Map;
|
|
295994
296056
|
const attachPromises = new WeakMap;
|
|
296057
|
+
const closePromises = new WeakMap;
|
|
296058
|
+
const evictions = new Set;
|
|
296059
|
+
function closeOnce(connection) {
|
|
296060
|
+
let closePromise = closePromises.get(connection);
|
|
296061
|
+
if (!closePromise) {
|
|
296062
|
+
closePromise = connection.close();
|
|
296063
|
+
closePromises.set(connection, closePromise);
|
|
296064
|
+
}
|
|
296065
|
+
return closePromise;
|
|
296066
|
+
}
|
|
295995
296067
|
const malloyConfig = new MalloyConfig(assembled.pojo, {
|
|
295996
296068
|
config: contextOverlay({ rootDirectory: environmentPath }),
|
|
295997
296069
|
gcpImpersonation: gcpImpersonationOverlay()
|
|
@@ -296045,13 +296117,28 @@ function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", is
|
|
|
296045
296117
|
throw new Error(`SSH proxy for connection '${name}' requires explicit host and ` + `port on the postgres connection; the connectionString form ` + `is not supported with a proxy.`);
|
|
296046
296118
|
}
|
|
296047
296119
|
connectionPromise = (async () => {
|
|
296048
|
-
const endpoint = await
|
|
296120
|
+
const endpoint = await openTunnel(metadata.proxy, {
|
|
296049
296121
|
host: pgConfig.host,
|
|
296050
296122
|
port: pgConfig.port
|
|
296051
296123
|
});
|
|
296052
296124
|
try {
|
|
296053
296125
|
const connection2 = buildProxiedPostgresConnection(metadata, endpoint);
|
|
296054
296126
|
proxyEndpoints.set(name, endpoint);
|
|
296127
|
+
endpoint.onClose((cause) => {
|
|
296128
|
+
if (proxyConnectionCache.get(name) !== connectionPromise) {
|
|
296129
|
+
return;
|
|
296130
|
+
}
|
|
296131
|
+
proxyConnectionCache.delete(name);
|
|
296132
|
+
proxyEndpoints.delete(name);
|
|
296133
|
+
logger.info("SSH tunnel died; rebuilding on the next query", { connection: name, error: cause?.message });
|
|
296134
|
+
const eviction = Promise.allSettled([
|
|
296135
|
+
closeOnce(connection2).catch((error) => logger.warn("Failed to close evicted proxied connection", { connection: name, error })),
|
|
296136
|
+
endpoint.close()
|
|
296137
|
+
]).then(() => {
|
|
296138
|
+
evictions.delete(eviction);
|
|
296139
|
+
});
|
|
296140
|
+
evictions.add(eviction);
|
|
296141
|
+
});
|
|
296055
296142
|
return connection2;
|
|
296056
296143
|
} catch (err) {
|
|
296057
296144
|
await endpoint.close().catch(() => {});
|
|
@@ -296143,8 +296230,9 @@ function buildEnvironmentMalloyConfig(connections = [], environmentPath = "", is
|
|
|
296143
296230
|
malloyConfig.shutdown("close"),
|
|
296144
296231
|
...wrapperPromises.map(async (promise) => {
|
|
296145
296232
|
const connection = await promise;
|
|
296146
|
-
await connection
|
|
296147
|
-
})
|
|
296233
|
+
await closeOnce(connection);
|
|
296234
|
+
}),
|
|
296235
|
+
...evictions
|
|
296148
296236
|
]);
|
|
296149
296237
|
const endpointResults = await Promise.allSettled([...proxyEndpoints.values()].map((ep) => ep.close()));
|
|
296150
296238
|
duckLakeCache.clear();
|
|
@@ -309149,9 +309237,6 @@ function providerKeyFor(provider) {
|
|
|
309149
309237
|
function sanitizeLunrQuery(query) {
|
|
309150
309238
|
return query.replace(/[~^:*+\-"]/g, " ").trim();
|
|
309151
309239
|
}
|
|
309152
|
-
function compareText(a, b) {
|
|
309153
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
|
309154
|
-
}
|
|
309155
309240
|
function round4(x2) {
|
|
309156
309241
|
return Math.round(x2 * 1e4) / 1e4;
|
|
309157
309242
|
}
|
|
@@ -316471,6 +316556,11 @@ var init_authorize = __esm(() => {
|
|
|
316471
316556
|
WHOLE_BODY_SINGLE_QUOTED_STRING = /^'(?:\\.|[^'\\])*'$/;
|
|
316472
316557
|
});
|
|
316473
316558
|
|
|
316559
|
+
// src/compare_text.ts
|
|
316560
|
+
function compareText(a, b) {
|
|
316561
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
316562
|
+
}
|
|
316563
|
+
|
|
316474
316564
|
// src/mcp/tools/package_entities.ts
|
|
316475
316565
|
import path7 from "path";
|
|
316476
316566
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -345977,7 +346067,7 @@ function computeSourceContentSha(packagePath, contentPaths, extra) {
|
|
|
345977
346067
|
return hash.digest("hex");
|
|
345978
346068
|
}
|
|
345979
346069
|
function canonicalJson(value) {
|
|
345980
|
-
return JSON.stringify(value, (_key, v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a
|
|
346070
|
+
return JSON.stringify(value, (_key, v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => compareText(a, b))) : v);
|
|
345981
346071
|
}
|
|
345982
346072
|
function boundedManifestValue(value) {
|
|
345983
346073
|
try {
|
|
@@ -346277,7 +346367,7 @@ function readAgentSkills(packagePath, realRoot, raw, paths, warnings) {
|
|
|
346277
346367
|
}
|
|
346278
346368
|
return {
|
|
346279
346369
|
roots,
|
|
346280
|
-
files: [...served].sort(([a], [b]) =>
|
|
346370
|
+
files: [...served].sort(([a], [b]) => compareText(a, b)).map(([relative_filepath, file_contents]) => ({
|
|
346281
346371
|
relative_filepath,
|
|
346282
346372
|
file_contents
|
|
346283
346373
|
})),
|
|
@@ -346378,7 +346468,7 @@ function resolveSkills(bundled, packageSkills) {
|
|
|
346378
346468
|
...packageSkills.filter((s2) => s2.name.includes("/") || !bundledNames.has(s2.name)).map((s2) => ({ ...s2, origin: "package" }))
|
|
346379
346469
|
];
|
|
346380
346470
|
}
|
|
346381
|
-
var BUNDLED_SKILLS, PACKAGE_SKILLS_DIR = "skills", PACKAGE_SKILL_FILE_MAX_BYTES, PACKAGE_AGENT_TEXT_MAX_BYTES, PACKAGE_AGENT_SKILLS_MAX_BYTES, AGENT_NAME, AGENT_KEYS, SCHEDULE_KEYS, BUDGET_KEYS, isObject2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), unknownKeys = (obj, known) => Object.keys(obj).filter((k) => !known.includes(k) && !k.startsWith("x-")),
|
|
346471
|
+
var BUNDLED_SKILLS, PACKAGE_SKILLS_DIR = "skills", PACKAGE_SKILL_FILE_MAX_BYTES, PACKAGE_AGENT_TEXT_MAX_BYTES, PACKAGE_AGENT_SKILLS_MAX_BYTES, AGENT_NAME, AGENT_KEYS, SCHEDULE_KEYS, BUDGET_KEYS, isObject2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), unknownKeys = (obj, known) => Object.keys(obj).filter((k) => !known.includes(k) && !k.startsWith("x-")), AgentProblem, emitSkillMd = (name, description2, body) => `---
|
|
346382
346472
|
name: ${JSON.stringify(name)}
|
|
346383
346473
|
description: ${JSON.stringify(description2)}
|
|
346384
346474
|
---
|
|
@@ -365844,6 +365934,9 @@ ${query}`;
|
|
|
365844
365934
|
getType() {
|
|
365845
365935
|
return this.modelType;
|
|
365846
365936
|
}
|
|
365937
|
+
getGivens() {
|
|
365938
|
+
return this.givens ?? [];
|
|
365939
|
+
}
|
|
365847
365940
|
getDeclaredQueryMetadata() {
|
|
365848
365941
|
if (this.declaredQueryMetadataMemo === undefined) {
|
|
365849
365942
|
this.declaredQueryMetadataMemo = composeDeclaredQueryMetadata({
|
|
@@ -368466,6 +368559,47 @@ var init_notebook_lint = __esm(() => {
|
|
|
368466
368559
|
init_report();
|
|
368467
368560
|
});
|
|
368468
368561
|
|
|
368562
|
+
// src/service/secure_givens.ts
|
|
368563
|
+
function summarizeSecureGivens(models, context = {}) {
|
|
368564
|
+
const byKey = new Map;
|
|
368565
|
+
for (const model of models) {
|
|
368566
|
+
if (!model.compiled)
|
|
368567
|
+
return;
|
|
368568
|
+
for (const given of model.givens) {
|
|
368569
|
+
if (given.secure !== true)
|
|
368570
|
+
continue;
|
|
368571
|
+
if (!given.name || !given.type) {
|
|
368572
|
+
logger.warn("A #(secure) given has no name or type; the package's secureGivens is left unreported", {
|
|
368573
|
+
packageName: context.packageName,
|
|
368574
|
+
modelPath: model.modelPath,
|
|
368575
|
+
name: given.name,
|
|
368576
|
+
type: given.type
|
|
368577
|
+
});
|
|
368578
|
+
return;
|
|
368579
|
+
}
|
|
368580
|
+
const key = `${given.name}\x00${given.type}`;
|
|
368581
|
+
let entry = byKey.get(key);
|
|
368582
|
+
if (!entry) {
|
|
368583
|
+
entry = {
|
|
368584
|
+
name: given.name,
|
|
368585
|
+
type: given.type,
|
|
368586
|
+
modelPaths: new Set
|
|
368587
|
+
};
|
|
368588
|
+
byKey.set(key, entry);
|
|
368589
|
+
}
|
|
368590
|
+
entry.modelPaths.add(model.modelPath);
|
|
368591
|
+
}
|
|
368592
|
+
}
|
|
368593
|
+
return Object.freeze([...byKey.values()].sort((a, b3) => compareText(a.name, b3.name) || compareText(a.type, b3.type)).map(({ name, type, modelPaths }) => Object.freeze({
|
|
368594
|
+
name,
|
|
368595
|
+
type,
|
|
368596
|
+
modelPaths: Object.freeze([...modelPaths].sort(compareText))
|
|
368597
|
+
})));
|
|
368598
|
+
}
|
|
368599
|
+
var init_secure_givens = __esm(() => {
|
|
368600
|
+
init_logger();
|
|
368601
|
+
});
|
|
368602
|
+
|
|
368469
368603
|
// src/service/persist_annotation_validation.ts
|
|
368470
368604
|
function assertPersistNamesQuoted(modelSource, modelPath) {
|
|
368471
368605
|
const unquoted = [];
|
|
@@ -368649,6 +368783,7 @@ var init_package2 = __esm(() => {
|
|
|
368649
368783
|
init_introspection_sql();
|
|
368650
368784
|
init_quoting();
|
|
368651
368785
|
init_model();
|
|
368786
|
+
init_secure_givens();
|
|
368652
368787
|
init_persist_annotation_validation();
|
|
368653
368788
|
init_package_load_gates();
|
|
368654
368789
|
import_recursive_readdir = __toESM(require_recursive_readdir(), 1);
|
|
@@ -368662,6 +368797,7 @@ var init_package2 = __esm(() => {
|
|
|
368662
368797
|
packageMetadata;
|
|
368663
368798
|
databases;
|
|
368664
368799
|
models = new Map;
|
|
368800
|
+
secureGivensMemo;
|
|
368665
368801
|
packagePath;
|
|
368666
368802
|
malloyConfig;
|
|
368667
368803
|
serveDestinationConfig;
|
|
@@ -368704,7 +368840,7 @@ var init_package2 = __esm(() => {
|
|
|
368704
368840
|
this.environmentName = environmentName;
|
|
368705
368841
|
this.packageName = packageName;
|
|
368706
368842
|
this.packagePath = packagePath;
|
|
368707
|
-
this.packageMetadata = packageMetadata;
|
|
368843
|
+
this.packageMetadata = Package.storableMetadata(packageMetadata);
|
|
368708
368844
|
this.databases = databases;
|
|
368709
368845
|
this.models = models;
|
|
368710
368846
|
this.malloyConfig = malloyConfig;
|
|
@@ -369244,6 +369380,19 @@ var init_package2 = __esm(() => {
|
|
|
369244
369380
|
getRetrievalSettings() {
|
|
369245
369381
|
return this.retrievalSettings;
|
|
369246
369382
|
}
|
|
369383
|
+
currentSecureGivens() {
|
|
369384
|
+
const memo = this.secureGivensMemo;
|
|
369385
|
+
if (memo?.forModels === this.models)
|
|
369386
|
+
return memo.value;
|
|
369387
|
+
const forModels = this.models;
|
|
369388
|
+
const value = summarizeSecureGivens([...forModels.entries()].map(([modelPath, model]) => ({
|
|
369389
|
+
modelPath,
|
|
369390
|
+
givens: model.getGivens(),
|
|
369391
|
+
compiled: model.getCompilationError() === undefined
|
|
369392
|
+
})), { packageName: this.packageName });
|
|
369393
|
+
this.secureGivensMemo = { forModels, value };
|
|
369394
|
+
return value;
|
|
369395
|
+
}
|
|
369247
369396
|
getPackageMetadata() {
|
|
369248
369397
|
const metadata = {
|
|
369249
369398
|
...this.packageMetadata,
|
|
@@ -369256,6 +369405,10 @@ var init_package2 = __esm(() => {
|
|
|
369256
369405
|
sourceContentSha: this.sourceContentSha,
|
|
369257
369406
|
agents: this.rawAgents === undefined ? undefined : this.listAgents()
|
|
369258
369407
|
};
|
|
369408
|
+
const secureGivens = this.currentSecureGivens();
|
|
369409
|
+
if (secureGivens !== undefined) {
|
|
369410
|
+
metadata.secureGivens = secureGivens;
|
|
369411
|
+
}
|
|
369259
369412
|
const warnings = this.exploreWarnings();
|
|
369260
369413
|
if (warnings.length > 0) {
|
|
369261
369414
|
metadata.exploresWarnings = warnings;
|
|
@@ -370406,8 +370559,14 @@ var init_package2 = __esm(() => {
|
|
|
370406
370559
|
setEnvironmentName(environmentName) {
|
|
370407
370560
|
this.environmentName = environmentName;
|
|
370408
370561
|
}
|
|
370562
|
+
static storableMetadata(packageMetadata) {
|
|
370563
|
+
if (!("secureGivens" in packageMetadata))
|
|
370564
|
+
return packageMetadata;
|
|
370565
|
+
const { secureGivens: _computed, ...stored } = packageMetadata;
|
|
370566
|
+
return stored;
|
|
370567
|
+
}
|
|
370409
370568
|
setPackageMetadata(packageMetadata) {
|
|
370410
|
-
this.packageMetadata = packageMetadata;
|
|
370569
|
+
this.packageMetadata = Package.storableMetadata(packageMetadata);
|
|
370411
370570
|
this.applyDiscoveryPolicyToModels();
|
|
370412
370571
|
this.applyQueryBoundaryToModels();
|
|
370413
370572
|
this.applySiblingModelResolverToModels();
|
|
@@ -375947,6 +376106,110 @@ var init_watch_mode_controller = __esm(() => {
|
|
|
375947
376106
|
MODEL_EXTS = new Set([".malloy", ".malloynb", ".md"]);
|
|
375948
376107
|
});
|
|
375949
376108
|
|
|
376109
|
+
// src/legacy_package_name.ts
|
|
376110
|
+
function splitLegacyPackageName(name) {
|
|
376111
|
+
if (typeof name !== "string")
|
|
376112
|
+
return;
|
|
376113
|
+
const at2 = name.lastIndexOf(LEGACY_VERSION_DELIMITER);
|
|
376114
|
+
if (at2 <= 0)
|
|
376115
|
+
return;
|
|
376116
|
+
const versionId = name.slice(at2 + LEGACY_VERSION_DELIMITER.length);
|
|
376117
|
+
if (!isSemver(versionId))
|
|
376118
|
+
return;
|
|
376119
|
+
return { packageName: name.slice(0, at2), versionId };
|
|
376120
|
+
}
|
|
376121
|
+
function recoverVersionFromName(packageName, versionId) {
|
|
376122
|
+
const unchanged = { packageName, versionId, recovered: false };
|
|
376123
|
+
if (!isVersioningEnabled())
|
|
376124
|
+
return unchanged;
|
|
376125
|
+
const split = splitLegacyPackageName(packageName);
|
|
376126
|
+
if (!split)
|
|
376127
|
+
return unchanged;
|
|
376128
|
+
const unnamed = versionId === undefined || versionId === null || versionId === "" || versionId === LATEST_VERSION_ALIAS;
|
|
376129
|
+
if (!unnamed && versionId !== split.versionId)
|
|
376130
|
+
return unchanged;
|
|
376131
|
+
warnOnce(packageName, split);
|
|
376132
|
+
return { ...split, recovered: true };
|
|
376133
|
+
}
|
|
376134
|
+
function legacyPackageNameMiddleware() {
|
|
376135
|
+
return (req, _res, next) => {
|
|
376136
|
+
const queryAt = req.url.indexOf("?");
|
|
376137
|
+
const pathname = queryAt < 0 ? req.url : req.url.slice(0, queryAt);
|
|
376138
|
+
const search = queryAt < 0 ? "" : req.url.slice(queryAt);
|
|
376139
|
+
const match = PACKAGE_PATH.exec(pathname);
|
|
376140
|
+
if (!match)
|
|
376141
|
+
return next();
|
|
376142
|
+
let segment;
|
|
376143
|
+
try {
|
|
376144
|
+
segment = decodeURIComponent(match[3]);
|
|
376145
|
+
} catch {
|
|
376146
|
+
return next();
|
|
376147
|
+
}
|
|
376148
|
+
const apiPrefix = match[1] ?? "";
|
|
376149
|
+
const recovered = recoverVersionFromName(segment, apiPrefix === "" ? undefined : req.query.versionId);
|
|
376150
|
+
if (!recovered.recovered)
|
|
376151
|
+
return next();
|
|
376152
|
+
const environment = match[2];
|
|
376153
|
+
const rest = match[4] ?? "";
|
|
376154
|
+
const pkg = encodeURIComponent(recovered.packageName);
|
|
376155
|
+
const version2 = encodeURIComponent(recovered.versionId);
|
|
376156
|
+
const packagePath = pathname.slice(0, pathname.length - match[3].length - rest.length);
|
|
376157
|
+
let path25 = `${packagePath}${pkg}${rest}`;
|
|
376158
|
+
const versionsOf = `${apiPrefix}/environments/${environment}/packages/${pkg}/versions/${version2}`;
|
|
376159
|
+
if (rest === "" && req.method === "DELETE") {
|
|
376160
|
+
path25 = versionsOf;
|
|
376161
|
+
} else if (rest === "" && req.method === "PATCH") {
|
|
376162
|
+
req.method = "PUT";
|
|
376163
|
+
path25 = `${versionsOf}/manifest`;
|
|
376164
|
+
}
|
|
376165
|
+
const params = new URLSearchParams(search.slice(1));
|
|
376166
|
+
params.set("versionId", recovered.versionId);
|
|
376167
|
+
req.url = `${path25}?${params.toString()}`;
|
|
376168
|
+
req.query.versionId = recovered.versionId;
|
|
376169
|
+
req[RECOVERED_VERSION] = recovered.versionId;
|
|
376170
|
+
next();
|
|
376171
|
+
};
|
|
376172
|
+
}
|
|
376173
|
+
function legacyPackageNameBodyMiddleware() {
|
|
376174
|
+
return (req, _res, next) => {
|
|
376175
|
+
const body = req.body;
|
|
376176
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
376177
|
+
return next();
|
|
376178
|
+
}
|
|
376179
|
+
if (req.method === "POST" && PACKAGE_COLLECTION_PATH.test(req.path)) {
|
|
376180
|
+
const recovered = recoverVersionFromName(body.name, undefined);
|
|
376181
|
+
if (recovered.recovered)
|
|
376182
|
+
body.name = recovered.packageName;
|
|
376183
|
+
return next();
|
|
376184
|
+
}
|
|
376185
|
+
const version2 = req[RECOVERED_VERSION];
|
|
376186
|
+
if (version2 !== undefined && (body.versionId === undefined || body.versionId === null || body.versionId === "")) {
|
|
376187
|
+
body.versionId = version2;
|
|
376188
|
+
}
|
|
376189
|
+
next();
|
|
376190
|
+
};
|
|
376191
|
+
}
|
|
376192
|
+
function warnOnce(combined, split) {
|
|
376193
|
+
if (warned.has(combined))
|
|
376194
|
+
return;
|
|
376195
|
+
if (warned.size >= WARNED_CAP)
|
|
376196
|
+
warned.clear();
|
|
376197
|
+
warned.add(combined);
|
|
376198
|
+
logger.warn(`versionId recovered from the package name ${combined}: package ` + `${split.packageName}, version ${split.versionId}. Pass the package ` + `name and versionId; reading the version from the name will be removed.`);
|
|
376199
|
+
}
|
|
376200
|
+
var LEGACY_VERSION_DELIMITER = "___", PACKAGE_PATH, PACKAGE_COLLECTION_PATH, RECOVERED_VERSION, warned, WARNED_CAP = 1e4;
|
|
376201
|
+
var init_legacy_package_name = __esm(() => {
|
|
376202
|
+
init_config();
|
|
376203
|
+
init_constants();
|
|
376204
|
+
init_logger();
|
|
376205
|
+
init_semver();
|
|
376206
|
+
init_version_service();
|
|
376207
|
+
PACKAGE_PATH = new RegExp(`^(${API_PREFIX})?/(?:environments|projects)/([^/]+)/packages/([^/]+)(/.*)?$`);
|
|
376208
|
+
PACKAGE_COLLECTION_PATH = new RegExp(`^${API_PREFIX}/(?:environments|projects)/[^/]+/packages/?$`);
|
|
376209
|
+
RECOVERED_VERSION = Symbol("recoveredVersionId");
|
|
376210
|
+
warned = new Set;
|
|
376211
|
+
});
|
|
376212
|
+
|
|
375950
376213
|
// src/heap_check.ts
|
|
375951
376214
|
import * as v8 from "v8";
|
|
375952
376215
|
function installHeapGauges() {
|
|
@@ -409101,6 +409364,7 @@ var init_main_server = __esm(async () => {
|
|
|
409101
409364
|
init_health();
|
|
409102
409365
|
init_instrumentation();
|
|
409103
409366
|
init_instrumentation();
|
|
409367
|
+
init_legacy_package_name();
|
|
409104
409368
|
init_logger();
|
|
409105
409369
|
init_config();
|
|
409106
409370
|
init_retrieval_config();
|
|
@@ -409221,6 +409485,7 @@ var init_main_server = __esm(async () => {
|
|
|
409221
409485
|
themeStore = new ThemeStore(environmentStore.storageManager, SERVER_ROOT);
|
|
409222
409486
|
themeController = new ThemeController(themeStore, SERVER_ROOT);
|
|
409223
409487
|
mcpApp = createMcpApp(environmentStore);
|
|
409488
|
+
app.use(legacyPackageNameMiddleware());
|
|
409224
409489
|
registerDataAppStaticRoutes(app, environmentStore, path29.join(path29.dirname(__filename_esm), "runtime", "publisher.js"));
|
|
409225
409490
|
if (!isDevelopment) {
|
|
409226
409491
|
app.use("/", import_express3.default.static(ROOT));
|
|
@@ -409239,6 +409504,7 @@ var init_main_server = __esm(async () => {
|
|
|
409239
409504
|
credentials: true
|
|
409240
409505
|
}));
|
|
409241
409506
|
app.use(import_body_parser3.default.json({ limit: "1mb" }));
|
|
409507
|
+
app.use(legacyPackageNameBodyMiddleware());
|
|
409242
409508
|
try {
|
|
409243
409509
|
const metricsHandler = getPrometheusMetricsHandler();
|
|
409244
409510
|
app.get("/metrics", metricsHandler);
|
package/package.json
CHANGED