@malloy-publisher/server 0.0.122 → 0.0.124
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 +25 -11
- package/dist/app/assets/{HomePage-z6NLKLPp.js → HomePage-zgjLbpTO.js} +1 -1
- package/dist/app/assets/{MainPage-C9McOjLb.js → MainPage-BD2RiQ6H.js} +1 -1
- package/dist/app/assets/{ModelPage-DjlTuT2G.js → ModelPage-BqzWWLvj.js} +1 -1
- package/dist/app/assets/{PackagePage-CDh_gnAZ.js → PackagePage-C-JViRAf.js} +1 -1
- package/dist/app/assets/{ProjectPage-vyvZZWAB.js → ProjectPage-CLlZgxV2.js} +1 -1
- package/dist/app/assets/{RouteError-FbxztVnz.js → RouteError-Bf0xYlO6.js} +1 -1
- package/dist/app/assets/{WorkbookPage-DNXFxaeZ.js → WorkbookPage-C7AyEw5d.js} +1 -1
- package/dist/app/assets/{index-DHFp2DLx.js → index-5F3gtdSl.js} +1 -1
- package/dist/app/assets/{index-a6hx_UrL.js → index-BUztoMie.js} +4 -4
- package/dist/app/assets/{index-BMyI9XZS.js → index-BWXd8Ctd.js} +1 -1
- package/dist/app/assets/{index.umd-Cv1NyZL8.js → index.umd-PbB35uhR.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/server.js +248 -156
- package/package.json +1 -1
- package/src/controller/connection.controller.ts +2 -3
- package/src/service/connection.ts +334 -213
- package/src/service/db_utils.ts +37 -52
- package/src/service/project.ts +5 -2
- package/tests/integration/mcp/mcp_transport.integration.spec.ts +4 -4
package/src/service/db_utils.ts
CHANGED
|
@@ -80,11 +80,20 @@ export async function getSchemasForConnection(
|
|
|
80
80
|
const bigquery = createBigQueryClient(connection);
|
|
81
81
|
const [datasets] = await bigquery.getDatasets();
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
const schemas = await Promise.all(
|
|
84
|
+
datasets.map(async (dataset) => {
|
|
85
|
+
const [metadata] = await dataset.getMetadata();
|
|
86
|
+
return {
|
|
87
|
+
name: dataset.id,
|
|
88
|
+
isHidden: false,
|
|
89
|
+
isDefault: false,
|
|
90
|
+
// Include description from dataset metadata if available
|
|
91
|
+
description: (metadata as { description?: string })
|
|
92
|
+
?.description,
|
|
93
|
+
};
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
return schemas;
|
|
88
97
|
} catch (error) {
|
|
89
98
|
console.error(
|
|
90
99
|
`Error getting schemas for BigQuery connection ${connection.name}:`,
|
|
@@ -213,35 +222,33 @@ export async function getSchemasForConnection(
|
|
|
213
222
|
// Use DuckDB's INFORMATION_SCHEMA.SCHEMATA to list schemas
|
|
214
223
|
// Use DISTINCT to avoid duplicates from attached databases
|
|
215
224
|
const result = await malloyConnection.runSQL(
|
|
216
|
-
"SELECT DISTINCT schema_name FROM information_schema.schemata ORDER BY schema_name",
|
|
225
|
+
"SELECT DISTINCT schema_name,catalog_name FROM information_schema.schemata ORDER BY catalog_name,schema_name",
|
|
226
|
+
{ rowLimit: 1000 },
|
|
217
227
|
);
|
|
218
228
|
|
|
219
229
|
const rows = standardizeRunSQLResult(result);
|
|
220
230
|
|
|
221
|
-
// Check if this DuckDB connection has attached databases
|
|
222
|
-
const hasAttachedDatabases =
|
|
223
|
-
connection.duckdbConnection?.attachedDatabases &&
|
|
224
|
-
Array.isArray(connection.duckdbConnection.attachedDatabases) &&
|
|
225
|
-
connection.duckdbConnection.attachedDatabases.length > 0;
|
|
226
|
-
|
|
227
231
|
return rows.map((row: unknown) => {
|
|
228
232
|
const typedRow = row as Record<string, unknown>;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
// If we have attached databases and this is not the main schema, prepend the attached database name
|
|
232
|
-
if (hasAttachedDatabases && schemaName !== "main") {
|
|
233
|
-
const attachedDbName = (
|
|
234
|
-
connection.duckdbConnection!.attachedDatabases as Array<{
|
|
235
|
-
name: string;
|
|
236
|
-
}>
|
|
237
|
-
)[0].name;
|
|
238
|
-
schemaName = `${attachedDbName}.${schemaName}`;
|
|
239
|
-
}
|
|
233
|
+
const schemaName = typedRow.schema_name as string;
|
|
234
|
+
const catalogName = typedRow.catalog_name as string;
|
|
240
235
|
|
|
241
236
|
return {
|
|
242
|
-
name: schemaName
|
|
243
|
-
isHidden:
|
|
244
|
-
|
|
237
|
+
name: `${catalogName}.${schemaName}`,
|
|
238
|
+
isHidden:
|
|
239
|
+
[
|
|
240
|
+
"information_schema",
|
|
241
|
+
"performance_schema",
|
|
242
|
+
"",
|
|
243
|
+
"SNOWFLAKE",
|
|
244
|
+
"information_schema",
|
|
245
|
+
"pg_catalog",
|
|
246
|
+
"pg_toast",
|
|
247
|
+
].includes(schemaName as string) ||
|
|
248
|
+
["md_information_schema", "system"].includes(
|
|
249
|
+
catalogName as string,
|
|
250
|
+
),
|
|
251
|
+
isDefault: catalogName === "main",
|
|
245
252
|
};
|
|
246
253
|
});
|
|
247
254
|
} catch (error) {
|
|
@@ -481,33 +488,11 @@ export async function listTablesForSchema(
|
|
|
481
488
|
throw new Error("DuckDB connection is required");
|
|
482
489
|
}
|
|
483
490
|
try {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
connection.duckdbConnection?.attachedDatabases &&
|
|
487
|
-
Array.isArray(connection.duckdbConnection.attachedDatabases) &&
|
|
488
|
-
connection.duckdbConnection.attachedDatabases.length > 0;
|
|
489
|
-
|
|
490
|
-
let actualSchemaName = schemaName;
|
|
491
|
-
|
|
492
|
-
// If we have attached databases and the schema name is prepended, extract the actual schema name
|
|
493
|
-
if (hasAttachedDatabases && schemaName.includes(".")) {
|
|
494
|
-
const attachedDbName = (
|
|
495
|
-
connection.duckdbConnection!.attachedDatabases as Array<{
|
|
496
|
-
name: string;
|
|
497
|
-
}>
|
|
498
|
-
)[0].name;
|
|
499
|
-
if (schemaName.startsWith(`${attachedDbName}.`)) {
|
|
500
|
-
actualSchemaName = schemaName.substring(
|
|
501
|
-
attachedDbName.length + 1,
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// Use DuckDB's INFORMATION_SCHEMA.TABLES to list tables in the specified schema
|
|
507
|
-
// This follows the DuckDB documentation for listing tables
|
|
508
|
-
// For DuckDB, we'll use string interpolation to avoid parameter binding issues
|
|
491
|
+
const catalogName = schemaName.split(".")[0];
|
|
492
|
+
schemaName = schemaName.split(".")[1];
|
|
509
493
|
const result = await malloyConnection.runSQL(
|
|
510
|
-
`SELECT table_name FROM information_schema.tables WHERE table_schema = '${
|
|
494
|
+
`SELECT table_name FROM information_schema.tables WHERE table_schema = '${schemaName}' and table_catalog = '${catalogName}' ORDER BY table_name`,
|
|
495
|
+
{ rowLimit: 1000 },
|
|
511
496
|
);
|
|
512
497
|
|
|
513
498
|
const rows = standardizeRunSQLResult(result);
|
package/src/service/project.ts
CHANGED
|
@@ -71,7 +71,10 @@ export class Project {
|
|
|
71
71
|
|
|
72
72
|
// Reload connections with full config
|
|
73
73
|
const { malloyConnections, apiConnections } =
|
|
74
|
-
await createProjectConnections(
|
|
74
|
+
await createProjectConnections(
|
|
75
|
+
payload.connections,
|
|
76
|
+
this.projectPath,
|
|
77
|
+
);
|
|
75
78
|
|
|
76
79
|
// Update the project's connection maps
|
|
77
80
|
this.malloyConnections = malloyConnections;
|
|
@@ -103,7 +106,7 @@ export class Project {
|
|
|
103
106
|
|
|
104
107
|
logger.info(`Creating project with connection configuration`);
|
|
105
108
|
const { malloyConnections, apiConnections } =
|
|
106
|
-
await createProjectConnections(connections);
|
|
109
|
+
await createProjectConnections(connections, projectPath);
|
|
107
110
|
|
|
108
111
|
logger.info(
|
|
109
112
|
`Loaded ${malloyConnections.size + apiConnections.length} connections for project ${projectName}`,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from "bun:test";
|
|
2
1
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
2
|
import {
|
|
4
3
|
ErrorCode,
|
|
5
|
-
Request,
|
|
6
4
|
Notification,
|
|
5
|
+
Request,
|
|
7
6
|
Result,
|
|
8
7
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
8
|
+
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
|
|
9
9
|
import { URL } from "url";
|
|
10
10
|
|
|
11
11
|
// --- Import E2E Test Setup ---
|
|
12
12
|
import {
|
|
13
|
+
cleanupE2ETestEnvironment,
|
|
13
14
|
McpE2ETestEnvironment,
|
|
14
15
|
setupE2ETestEnvironment,
|
|
15
|
-
cleanupE2ETestEnvironment,
|
|
16
16
|
} from "../../harness/mcp_test_setup";
|
|
17
17
|
|
|
18
18
|
// --- Test Suite ---
|
|
@@ -42,7 +42,7 @@ describe("MCP Transport Tests (E2E Integration)", () => {
|
|
|
42
42
|
expect(result).toHaveProperty("resources");
|
|
43
43
|
expect(Array.isArray(result.resources)).toBe(true);
|
|
44
44
|
},
|
|
45
|
-
{ timeout:
|
|
45
|
+
{ timeout: 15000 },
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
it("should receive InvalidParams error when calling a known method with invalid params", async () => {
|