@malloy-publisher/server 0.0.226 → 0.0.227

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.
Files changed (69) hide show
  1. package/README.md +2 -11
  2. package/dist/package_load_worker.mjs +86 -24
  3. package/dist/server.mjs +655 -6994
  4. package/package.json +1 -4
  5. package/src/health.ts +3 -8
  6. package/src/mcp/error_messages.ts +8 -37
  7. package/src/mcp/handler_utils.ts +10 -129
  8. package/src/mcp/mcp_constants.ts +0 -16
  9. package/src/mcp/{agent_server.protocol.spec.ts → server.protocol.spec.ts} +14 -12
  10. package/src/mcp/server.ts +29 -37
  11. package/src/mcp/skills/build_skills_bundle.ts +1 -1
  12. package/src/mcp/skills/skills_bundle.json +1 -1
  13. package/src/mcp/tools/docs_search_tool.ts +1 -1
  14. package/src/mcp/tools/execute_query_tool.ts +2 -2
  15. package/src/mcp/tools/get_context_eval.ts +3 -3
  16. package/src/mcp/tools/get_context_tool.spec.ts +196 -1
  17. package/src/mcp/tools/get_context_tool.ts +165 -67
  18. package/src/package_load/package_load_pool.ts +3 -0
  19. package/src/package_load/package_load_worker.ts +68 -24
  20. package/src/package_load/protocol.ts +16 -0
  21. package/src/package_load/rpc_wait_accountant.spec.ts +109 -0
  22. package/src/package_load/rpc_wait_accountant.ts +76 -0
  23. package/src/package_load_metrics.spec.ts +114 -0
  24. package/src/package_load_metrics.ts +127 -0
  25. package/src/pg_helpers.spec.ts +2 -206
  26. package/src/pg_helpers.ts +4 -120
  27. package/src/server.ts +0 -16
  28. package/src/service/environment.ts +1 -1
  29. package/src/service/package.ts +82 -42
  30. package/src/test_helpers/metrics_harness.ts +40 -0
  31. package/tests/harness/mcp_test_setup.ts +1 -1
  32. package/tests/integration/mcp/mcp_transport.integration.spec.ts +7 -31
  33. package/tests/integration/watch-mode/watch_mode.integration.spec.ts +0 -6
  34. package/dxt/malloy_bridge.py +0 -354
  35. package/dxt/manifest.json +0 -22
  36. package/src/dto/connection.dto.spec.ts +0 -186
  37. package/src/dto/connection.dto.ts +0 -308
  38. package/src/dto/index.ts +0 -2
  39. package/src/dto/package.dto.spec.ts +0 -42
  40. package/src/dto/package.dto.ts +0 -27
  41. package/src/dto/validate.spec.ts +0 -76
  42. package/src/dto/validate.ts +0 -31
  43. package/src/ducklake_version.spec.ts +0 -43
  44. package/src/ducklake_version.ts +0 -26
  45. package/src/mcp/agent_server.spec.ts +0 -18
  46. package/src/mcp/agent_server.ts +0 -144
  47. package/src/mcp/prompts/handlers.ts +0 -84
  48. package/src/mcp/prompts/index.ts +0 -11
  49. package/src/mcp/prompts/prompt_definitions.ts +0 -160
  50. package/src/mcp/prompts/prompt_service.ts +0 -67
  51. package/src/mcp/prompts/utils.ts +0 -62
  52. package/src/mcp/resource_metadata.ts +0 -47
  53. package/src/mcp/resources/environment_resource.ts +0 -187
  54. package/src/mcp/resources/model_resource.ts +0 -155
  55. package/src/mcp/resources/notebook_resource.ts +0 -137
  56. package/src/mcp/resources/package_resource.ts +0 -373
  57. package/src/mcp/resources/query_resource.ts +0 -122
  58. package/src/mcp/resources/source_resource.ts +0 -141
  59. package/src/mcp/resources/view_resource.ts +0 -136
  60. package/src/mcp/tools/discovery_tools.ts +0 -280
  61. package/src/storage/BaseRepository.ts +0 -31
  62. package/src/storage/StorageManager.mock.ts +0 -50
  63. package/tests/harness/e2e.ts +0 -96
  64. package/tests/harness/mocks.ts +0 -39
  65. package/tests/harness/uris.ts +0 -31
  66. package/tests/integration/mcp/mcp_resource.integration.spec.ts +0 -655
  67. package/tests/integration/mcp/setup.spec.ts +0 -5
  68. package/tests/unit/mcp/prompt_definitions.test.ts +0 -102
  69. package/tests/unit/mcp/prompt_happy.test.ts +0 -51
@@ -1,136 +0,0 @@
1
- import {
2
- McpServer,
3
- ResourceTemplate,
4
- } from "@modelcontextprotocol/sdk/server/mcp.js";
5
- import { URL } from "url";
6
- import type { components } from "../../api"; // Need this for View definition type
7
- import { ModelCompilationError } from "../../errors";
8
- import { logger } from "../../logger";
9
- import { EnvironmentStore } from "../../service/environment_store";
10
- import {
11
- getInternalError,
12
- getMalloyErrorDetails,
13
- getNotFoundError,
14
- } from "../error_messages";
15
- import {
16
- getModelForQuery,
17
- handleResourceGet,
18
- McpGetResourceError,
19
- } from "../handler_utils";
20
- import { RESOURCE_METADATA } from "../resource_metadata";
21
-
22
- // Define the expected parameter types
23
- type ViewParams = {
24
- environmentName?: unknown;
25
- packageName?: unknown;
26
- modelPath?: unknown;
27
- sourceName?: unknown;
28
- viewName?: unknown;
29
- };
30
-
31
- /**
32
- * Registers the Malloy View resource type (nested within a Source).
33
- */
34
- export function registerViewResource(
35
- mcpServer: McpServer,
36
- environmentStore: EnvironmentStore,
37
- ): void {
38
- mcpServer.resource(
39
- "view",
40
- new ResourceTemplate(
41
- "malloy://environment/{environmentName}/package/{packageName}/models/{modelPath}/sources/{sourceName}/views/{viewName}",
42
- { list: undefined }, // Listing views is not supported via this template
43
- ),
44
- (uri, params) =>
45
- handleResourceGet(
46
- uri,
47
- params as ViewParams,
48
- "view",
49
- async (
50
- {
51
- environmentName,
52
- packageName,
53
- modelPath,
54
- sourceName,
55
- viewName,
56
- }: ViewParams,
57
- uri: URL,
58
- ) => {
59
- if (
60
- typeof environmentName !== "string" ||
61
- typeof packageName !== "string" ||
62
- typeof modelPath !== "string" ||
63
- typeof sourceName !== "string" ||
64
- typeof viewName !== "string"
65
- ) {
66
- throw new Error("Invalid parameters for view resource.");
67
- }
68
-
69
- try {
70
- const modelResult = await getModelForQuery(
71
- environmentStore,
72
- environmentName,
73
- packageName,
74
- modelPath,
75
- );
76
- if ("error" in modelResult) {
77
- throw new McpGetResourceError(modelResult.error);
78
- }
79
- const { model } = modelResult;
80
-
81
- const sources = await model.getSources();
82
- if (!sources) {
83
- throw new Error("Could not retrieve sources from model.");
84
- }
85
- const source = sources.find(
86
- (s: components["schemas"]["Source"]) =>
87
- s.name === sourceName,
88
- );
89
- if (!source) {
90
- throw new McpGetResourceError(
91
- getNotFoundError(
92
- `Source '${sourceName}' in model '${modelPath}' package '${packageName}' environment '${environmentName}'`,
93
- ),
94
- );
95
- }
96
-
97
- // Find the view within the source
98
- const view = source.views?.find(
99
- (v: components["schemas"]["View"]) => v.name === viewName,
100
- );
101
-
102
- if (!view) {
103
- // Specific "View not found" error
104
- const errorDetails = getNotFoundError(
105
- `View '${viewName}' in source '${sourceName}' model '${modelPath}' package '${packageName}' environment '${environmentName}'`,
106
- );
107
- throw new McpGetResourceError(errorDetails);
108
- }
109
- return view;
110
- } catch (error) {
111
- if (error instanceof McpGetResourceError) {
112
- throw error; // Re-throw already formatted
113
- }
114
- if (error instanceof ModelCompilationError) {
115
- const errorDetails = getMalloyErrorDetails(
116
- "GetResource (view - model compilation)",
117
- `${environmentName}/${packageName}/${modelPath}`,
118
- error,
119
- );
120
- throw new McpGetResourceError(errorDetails);
121
- }
122
- logger.error(
123
- `[MCP Server Error] Error fetching view '${viewName}' from ${uri.href}:`,
124
- { error },
125
- );
126
- const fallbackErrorDetails = getInternalError(
127
- `GetResource (view: ${uri.href})`,
128
- error,
129
- );
130
- throw new McpGetResourceError(fallbackErrorDetails);
131
- }
132
- },
133
- RESOURCE_METADATA.view,
134
- ),
135
- );
136
- }
@@ -1,280 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { z } from "zod";
3
- import { EnvironmentStore } from "../../service/environment_store";
4
- import { buildMalloyUri } from "../handler_utils";
5
-
6
- const listPackagesShape = {
7
- environmentName: z
8
- .string()
9
- .describe(
10
- "Environment name. Names are listed in the malloy_environmentList tool.",
11
- ),
12
- };
13
- type listPackagesParams = z.infer<z.ZodObject<typeof listPackagesShape>>;
14
-
15
- const getModelsShape = {
16
- environmentName: z
17
- .string()
18
- .describe(
19
- "Environment name. Names are listed in the malloy_environmentList tool.",
20
- ),
21
- packageName: z
22
- .string()
23
- .describe(
24
- "Package name. Package names are listed in the listPackages tool.",
25
- ),
26
- };
27
- type getModelsParams = z.infer<z.ZodObject<typeof getModelsShape>>;
28
-
29
- const getModelTextShape = {
30
- environmentName: z
31
- .string()
32
- .describe(
33
- "Environment name. Names are listed in the malloy_environmentList tool.",
34
- ),
35
- packageName: z
36
- .string()
37
- .describe(
38
- "Package name. Package names are listed in the listPackages tool.",
39
- ),
40
- modelPath: z
41
- .string()
42
- .describe(
43
- "Model path. Model paths are listed in the malloy_packageGet tool.",
44
- ),
45
- };
46
- type getModelTextParams = z.infer<z.ZodObject<typeof getModelTextShape>>;
47
-
48
- /**
49
- * Registers Malloy discovery tools with the MCP server.
50
- * Lists environments and packages for navigation.
51
- */
52
- export function registerTools(
53
- mcpServer: McpServer,
54
- environmentStore: EnvironmentStore,
55
- ): void {
56
- mcpServer.tool(
57
- "malloy_environmentList",
58
- "Lists all Malloy environments",
59
- {},
60
- async () => {
61
- console.log(
62
- "[MCP LOG] Entering ListResources (environment) handler (listing ALL packages)...",
63
- );
64
- const allEnvironments = await Promise.all(
65
- (await environmentStore.listEnvironments())
66
- .filter((environment) => environment.name)
67
- .map((environment) => ({
68
- name: environment.name,
69
- environment: environmentStore.getEnvironment(
70
- environment.name!,
71
- false,
72
- ),
73
- })),
74
- );
75
-
76
- console.log(
77
- `[MCP LOG] Found ${allEnvironments.length} environments defined.`,
78
- );
79
-
80
- const mappedResources = await Promise.all(
81
- allEnvironments.map(async (environment) => {
82
- const name = environment.name;
83
- const environmentInstance = await environment.environment;
84
- const metadata =
85
- await environmentInstance.reloadEnvironmentMetadata();
86
- const readme = metadata.readme;
87
- return {
88
- name,
89
- type: "environment",
90
- description: readme || "NO Description available",
91
- };
92
- }),
93
- );
94
- console.log(
95
- `[MCP LOG] ListResources (environment): Returning ${mappedResources.length} package resources.`,
96
- );
97
- return {
98
- content: [
99
- {
100
- type: "resource",
101
- resource: {
102
- type: "application/json",
103
- uri: buildMalloyUri({}, "environment"),
104
- text: JSON.stringify(mappedResources),
105
- },
106
- },
107
- ],
108
- };
109
- },
110
- );
111
-
112
- mcpServer.tool(
113
- "malloy_packageList",
114
- "Lists all Malloy packages within an environment",
115
- listPackagesShape,
116
- async (params: listPackagesParams) => {
117
- const { environmentName } = params;
118
- console.log(
119
- "[MCP LOG] Entering ListResources (environment) handler (listing ALL packages)...",
120
- );
121
- const environment = await environmentStore.getEnvironment(
122
- environmentName,
123
- false,
124
- );
125
- const packages = await environment.listPackages();
126
- console.log(`[MCP LOG] Found ${packages.length} packages defined.`);
127
- const mappedResources = packages.map((pkg) => ({
128
- modelPath: pkg.name,
129
- type: "package",
130
- description: pkg.description,
131
- }));
132
- console.log(
133
- `[MCP LOG] ListResources (environment): Returning ${mappedResources.length} package resources.`,
134
- );
135
- return {
136
- content: [
137
- {
138
- type: "resource",
139
- resource: {
140
- type: "application/json",
141
- uri: buildMalloyUri(
142
- { environment: environmentName },
143
- "package",
144
- ),
145
- text: JSON.stringify(mappedResources),
146
- },
147
- },
148
- ],
149
- };
150
- },
151
- );
152
-
153
- mcpServer.tool(
154
- "malloy_packageGet",
155
- "Lists resources within a package",
156
- getModelsShape,
157
- async (params: getModelsParams) => {
158
- const { environmentName, packageName } = params;
159
- console.log(
160
- "[MCP LOG] Entering GetResources (environment) handler (listing ALL packages)...",
161
- );
162
- const environment = await environmentStore.getEnvironment(
163
- environmentName,
164
- false,
165
- );
166
- const pkg = await environment.getPackage(packageName, false);
167
- const models = await pkg.listModels();
168
- console.log(`[MCP LOG] Found ${models.length} models defined.`);
169
- const mappedResources = models.map((model) => ({
170
- name: model.path,
171
- type: "model",
172
- }));
173
- console.log(
174
- `[MCP LOG] ListResources (environment): Returning ${mappedResources.length} package resources.`,
175
- );
176
- return {
177
- content: [
178
- {
179
- type: "resource",
180
- resource: {
181
- type: "application/json",
182
- uri: buildMalloyUri(
183
- {
184
- environment: environmentName,
185
- package: packageName,
186
- },
187
- "model",
188
- ),
189
- text: JSON.stringify(mappedResources),
190
- },
191
- },
192
- ],
193
- };
194
- },
195
- );
196
-
197
- mcpServer.tool(
198
- "malloy_modelGetText",
199
- "Gets the raw text content of a model file",
200
- getModelTextShape,
201
- async (params: getModelTextParams) => {
202
- const { environmentName, packageName, modelPath } = params;
203
- console.log(
204
- `[MCP LOG] Entering GetModelText handler for ${environmentName}/${packageName}/${modelPath}...`,
205
- );
206
-
207
- try {
208
- const environment = await environmentStore.getEnvironment(
209
- environmentName,
210
- false,
211
- );
212
- const pkg = await environment.getPackage(packageName, false);
213
- const model = pkg.getModel(modelPath);
214
-
215
- if (!model) {
216
- console.log(
217
- "model not found",
218
- modelPath,
219
- "in ",
220
- pkg.listModels(),
221
- );
222
- throw new Error(`Model not found: ${modelPath}`);
223
- }
224
-
225
- // Route through the Environment so the disk read is serialized
226
- // against installPackage / deletePackage.
227
- const fileText = await environment.getModelFileText(
228
- packageName,
229
- modelPath,
230
- );
231
-
232
- console.log(
233
- `[MCP LOG] Successfully retrieved model text for ${modelPath}`,
234
- );
235
- return {
236
- content: [
237
- {
238
- type: "resource",
239
- resource: {
240
- type: "text/plain",
241
- uri: buildMalloyUri(
242
- {
243
- environment: environmentName,
244
- package: packageName,
245
- model: modelPath,
246
- },
247
- "model-text",
248
- ),
249
- text: fileText,
250
- },
251
- },
252
- ],
253
- };
254
- } catch (error) {
255
- console.error(`[MCP LOG] Error retrieving model text: ${error}`);
256
- const errorMessage =
257
- error instanceof Error ? error.message : "Unknown error";
258
- return {
259
- content: [
260
- {
261
- type: "resource",
262
- resource: {
263
- type: "text/plain",
264
- uri: buildMalloyUri(
265
- {
266
- environment: environmentName,
267
- package: packageName,
268
- model: modelPath,
269
- },
270
- "model-text",
271
- ),
272
- text: `Error: ${errorMessage}`,
273
- },
274
- },
275
- ],
276
- };
277
- }
278
- },
279
- );
280
- }
@@ -1,31 +0,0 @@
1
- import { DatabaseConnection } from "./DatabaseInterface";
2
-
3
- export abstract class BaseRepository {
4
- constructor(protected db: DatabaseConnection) {}
5
-
6
- protected generateId(): string {
7
- return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
8
- }
9
-
10
- protected now(): Date {
11
- return new Date();
12
- }
13
-
14
- protected async executeQuery<T>(
15
- _query: string,
16
- _params?: unknown[],
17
- ): Promise<T[]> {
18
- // This will be implemented by specific database implementations
19
- throw new Error(
20
- "executeQuery must be implemented by database-specific class",
21
- );
22
- }
23
-
24
- protected async executeOne<T>(
25
- query: string,
26
- params?: unknown[],
27
- ): Promise<T | null> {
28
- const results = await this.executeQuery<T>(query, params);
29
- return results.length > 0 ? results[0] : null;
30
- }
31
- }
@@ -1,50 +0,0 @@
1
- type MockData = Record<string, unknown>;
2
-
3
- export class StorageManager {
4
- async initialize(): Promise<void> {
5
- return;
6
- }
7
-
8
- getRepository() {
9
- return {
10
- listEnvironments: async (): Promise<unknown[]> => [],
11
- createEnvironment: async (data: MockData): Promise<MockData> => ({
12
- id: "test-id",
13
- ...data,
14
- }),
15
- updateEnvironment: async (
16
- id: string,
17
- data: MockData,
18
- ): Promise<MockData> => ({
19
- id,
20
- ...data,
21
- }),
22
- getPackages: async (): Promise<unknown[]> => [],
23
- createPackage: async (data: MockData): Promise<MockData> => ({
24
- id: "test-id",
25
- ...data,
26
- }),
27
- updatePackage: async (
28
- id: string,
29
- data: MockData,
30
- ): Promise<MockData> => ({
31
- id,
32
- ...data,
33
- }),
34
- deletePackage: async (): Promise<void> => {},
35
- getConnections: async (): Promise<unknown[]> => [],
36
- createConnection: async (data: MockData): Promise<MockData> => ({
37
- id: "test-id",
38
- ...data,
39
- }),
40
- updateConnection: async (
41
- id: string,
42
- data: MockData,
43
- ): Promise<MockData> => ({
44
- id,
45
- ...data,
46
- }),
47
- deleteConnection: async (): Promise<void> => {},
48
- };
49
- }
50
- }
@@ -1,96 +0,0 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
- import type {
4
- Notification,
5
- Request,
6
- Result,
7
- } from "@modelcontextprotocol/sdk/types.js";
8
- import http from "http";
9
- import path from "path";
10
- import { fileURLToPath } from "url";
11
- import { URL } from "url";
12
-
13
- /**
14
- * E2E environment descriptor returned by {@link startE2E}.
15
- */
16
- export interface E2EEnv {
17
- httpServer: http.Server;
18
- serverUrl: string;
19
- mcpClient: Client<Request, Notification, Result>;
20
- }
21
-
22
- let originalServerRoot: string | undefined;
23
-
24
- /**
25
- * Spin-up the real Express app (via mcp/server.ts), expose its base URL and
26
- * return a fully-connected MCP client. The caller **must** invoke {@link stop}
27
- * once its suite finishes.
28
- */
29
- export async function startE2E(): Promise<E2EEnv & { stop(): Promise<void> }> {
30
- //--------------------------------------------------------------------------
31
- // 1. Set SERVER_ROOT so EnvironmentStore loader finds publisher.config.json
32
- //--------------------------------------------------------------------------
33
- originalServerRoot = process.env.SERVER_ROOT;
34
- // Use import.meta.url for cross-platform compatibility (works on Windows)
35
- const __filename = fileURLToPath(import.meta.url);
36
- const __dirname = path.dirname(__filename);
37
- const serverPackageDir = path.resolve(__dirname, "../../../"); // packages/server
38
- process.env.SERVER_ROOT = serverPackageDir;
39
-
40
- //--------------------------------------------------------------------------
41
- // 2. Dynamically import the configured Express app AFTER env var mutation
42
- //--------------------------------------------------------------------------
43
- const { mcpApp } = await import("../../src/server");
44
-
45
- //--------------------------------------------------------------------------
46
- // 3. Start HTTP server on a predictable high port (4042 by default)
47
- //--------------------------------------------------------------------------
48
- const TEST_PORT = Number(process.env.MCP_PORT || 4040) + 2;
49
-
50
- const httpServer: http.Server = await new Promise<http.Server>(
51
- (resolve, reject) => {
52
- const srv = http
53
- .createServer(mcpApp)
54
- .listen(TEST_PORT, "127.0.0.1", () => resolve(srv));
55
-
56
- srv.on("error", (err: NodeJS.ErrnoException) => {
57
- /* c8 ignore next 3 */
58
- console.error("[E2E] server listen error", err);
59
- reject(err);
60
- });
61
- },
62
- );
63
-
64
- const serverUrl = `http://127.0.0.1:${TEST_PORT}`;
65
-
66
- //--------------------------------------------------------------------------
67
- // 4. Connect MCP client over HTTP streaming bridge
68
- //--------------------------------------------------------------------------
69
- const mcpClient = new Client<Request, Notification, Result>({
70
- name: "mcp-e2e-client",
71
- version: "1.0",
72
- });
73
-
74
- const transport = new StreamableHTTPClientTransport(
75
- new URL(`${serverUrl}/mcp`),
76
- );
77
-
78
- await mcpClient.connect(transport);
79
-
80
- //--------------------------------------------------------------------------
81
- // 5. Return env + graceful stop helper
82
- //--------------------------------------------------------------------------
83
- const stop = async (): Promise<void> => {
84
- try {
85
- await mcpClient.close();
86
- } finally {
87
- httpServer.closeAllConnections?.();
88
- await new Promise<void>((r) => httpServer.close(() => r()));
89
- // Restore SERVER_ROOT
90
- if (originalServerRoot === undefined) delete process.env.SERVER_ROOT;
91
- else process.env.SERVER_ROOT = originalServerRoot;
92
- }
93
- };
94
-
95
- return { httpServer, serverUrl, mcpClient, stop };
96
- }
@@ -1,39 +0,0 @@
1
- import sinon from "sinon";
2
- import { EnvironmentStore } from "../../src/service/environment_store";
3
-
4
- /** Return a stubbed EnvironmentStore where every lookup throws or returns minimal objects. */
5
- export function fakeEnvironmentStore(): sinon.SinonStubbedInstance<EnvironmentStore> {
6
- const es = sinon.createStubInstance(EnvironmentStore);
7
- // For now just have getEnvironment reject; suites can stub more.
8
- es.getEnvironment.rejects(
9
- new Error("fakeEnvironmentStore: getEnvironment not stubbed"),
10
- );
11
- return es;
12
- }
13
-
14
- // The runtime implementation of `McpServer` lives in the MCP SDK package, which
15
- // is **not** required for unit/integration tests that only need a stubbed
16
- // instance. Importing it at runtime would fail when the dependency is not
17
- // present in the local workspace. Instead we define a minimal dummy class that
18
- // satisfies Sinon while keeping the public type surface the same for tests.
19
- //
20
- // NOTE: If we later add the real SDK as a dependency we can simply replace this
21
- // dummy class with:
22
- // import { McpServer } from "@modelcontextprotocol/sdk";
23
- class DummyMcpServer {}
24
-
25
- // Re-export the symbol so downstream test files can continue to refer to the
26
- // name `McpServer` without changes.
27
- export type McpServer = DummyMcpServer;
28
-
29
- /** Convenience helper mimicking the old mocks used in integration specs. */
30
- export function createMalloyServiceMocks() {
31
- return {
32
- environmentStore: fakeEnvironmentStore(),
33
- } as const;
34
- }
35
-
36
- /** Create a Sinon spy wrapper around a new DummyMcpServer instance. */
37
- export function spyMcpServer(): sinon.SinonStubbedInstance<DummyMcpServer> {
38
- return sinon.createStubInstance(DummyMcpServer);
39
- }
@@ -1,31 +0,0 @@
1
- export interface FixtureUris {
2
- project: string;
3
- package: string;
4
- flightsModel: string;
5
- source: string;
6
- view: string;
7
- query: string;
8
- notebook: string;
9
- }
10
-
11
- /**
12
- * Return canonical URIs used across integration tests, parametrised by project
13
- * and package. Most suites will call this with defaults.
14
- */
15
- export function malloyUris(
16
- project = "malloy-samples",
17
- pkg = "faa",
18
- ): FixtureUris {
19
- const base = `malloy://project/${project}`;
20
- const pkgUri = `${base}/package/${pkg}`;
21
- const model = `${pkgUri}/models/flights.malloy`;
22
- return {
23
- project: base,
24
- package: pkgUri,
25
- flightsModel: model,
26
- source: `${model}/sources/flights`,
27
- view: `${model}/sources/flights/views/flights_by_month`,
28
- query: `${model}/queries/flights_by_carrier`,
29
- notebook: `${pkgUri}/notebooks/overview.malloynb`,
30
- };
31
- }